Pull to refresh
73
0
Ilya Khokhryakov @awolf

User

Send message

«Never say never» или Работаем с таймзонами правильно

Reading time 9 min
Views 73K
Эта статья рассказывает о проблемах, которые поджидают программиста, работающего с часовыми поясами. В теории, вроде, всё хорошо, просто и понятно, но жизнь — штука сложная, и на практике, порой, возникают совершенно неожиданные ситуации.

TL;DR: Работа с таймзонами — это боль и унижение. Никогда не работайте с таймзонами!

Итак, все кругом твердят вам, что при получении времени от пользователя нужно сразу же переводить его в UTC, работать со временем нужно только в UTC и хранить время тоже нужно строго в UTC. Совет, на первый взгляд, выглядит разумным, и следование ему делает вашу жизнь проще… Если только ваша программа не предполагает сложной работы с датами. Записать в базу данных дату и время регистрации пользователя на сайте? Сохранить время отправки сообщения или дату создания заказа в интернет-магазине? Вывести сообщение в лог с указанием даты-времени? Используйте UTC и всё будет в порядке, можете даже не читать эту статью дальше. Любое текущее время можно совершенно спокойно конвертировать в UTC и забыть о проблемах. Но что, если мы хотим работать с временем в будущем? Или в прошлом? Например, если мы пишем сервис календаря, или сервис для отложенной отправки сообщений?

Читать дальше →
Total votes 84: ↑79 and ↓5 +74
Comments 103

Разделяй и властвуй: как мы реализовывали разделение сессий на портале Mail.Ru

Reading time 7 min
Views 41K


Mail.Ru — огромный портал, существующий более 15-ти лет. За это время мы прошли путь от небольшого веб-проекта до самого посещаемого сайта рунета. В состав портала входит огромное количество сервисов, у каждого из которых своя судьба, и над каждым из которых работает отдельная команда. Разработчикам пришлось как следует потрудиться, чтобы на всех проектах — и новых, и старых, и тех, которые присоединились к порталу по мере его развития, — использовалась единая система авторизации. А через много лет перед нами встала фактически обратная задача: разделить пользовательские сессии. О том, зачем мы это делали, какие трудности нас ожидали и как мы их обошли, я расскажу в этом посте.
Читать дальше →
Total votes 142: ↑125 and ↓17 +108
Comments 31

Список оптимизаций рендеринга DOM, реализуемых на уровне Javascript фреймворка

Reading time 13 min
Views 26K
С октября 2009 года я занимаюсь разработкой приложения для поиска и прослушивания музыки. Я стремлюсь организовать возможность быстрого взаимодействия пользователя с интерфейсом, и в качестве одного из средств ускорения взаимодействия использую различные способы для быстрой отрисовки страниц.

Предлагаю ознакомиться со способами, реализованными мной в приложении на системном уровне:

  • Использование CSS и переключение классов вместо перестроения DOM дерева
  • Повсемнестное кеширование выборок элементов ($('div.active_part span.highlighter')), атомарные операции по изменению (вместо всеобщей перерисовки, вместо переделывания больших участков DOM дерева)
  • Минимизации чтений DOM во время записи изменений состояний
  • Кеширование размеров и расположения элементов (это спасает от излишнего вычисления при считывании этих значений при наличии других изменений: чтение во время изменения множества частей дерева крайне негативно сказывается на производительности)
  • Аккуратное, не затягивающееся накопление изменений, необходимых произвести в DOM
  • Прикрепление частей изменяющихся коллекций единовременно (когда, например, в середину списка вставляется 3 новых элемента; createDocumentFragment) в конкретное место (after, before) вместо открепления всей коллекции от DOM и повторного прикрепления (и вместо того, чтобы перерисовывать весь список)
  • Прогрессивный асинхронный рендеринг: картина прорисовывается сразу с небольшим количеством деталей, затем деталей появляется всё больше
  • Клонирование нодов (как часть шаблонизации)
  • Кеширование и использование кеша результатов парсинга DOM шаблонов


image image
изображения из части с заголовком «Прикрепление частей изменяющихся коллекций единовременно...»
Читать дальше →
Total votes 68: ↑66 and ↓2 +64
Comments 31

Подборка трюков при анализе защищенности веб приложений

Reading time 5 min
Views 35K
Всем привет! Этот топик посвящен разным трюкам при анализе защищенности (пентесте) веб приложений. Периодически сталкиваешься с ситуацией, когда надо обойти какую-нибудь защиту, выкрутиться в данных ограничениях или просто протестировать какое-то неочевидное место. И этот пост как раз об этом! Добро пожаловать под кат.
Читать дальше →
Total votes 87: ↑81 and ↓6 +75
Comments 16

Результаты исследования методов аутентификации и некоторых механизмов защиты от WEB-атак на примере Google, VK и других

Reading time 5 min
Views 46K

О чем топик?


В этой статье я расскажу о реализациях разного функционала (преимущественно, на веб-сервисах) для обеспечения безопасности пользователей на примере «гигантов» современной IT индустрии. Данный материал будет полезен разработчикам, архитекторам, тим-лидам и менеджерам при постановке задач схожего функционала. Реализации в статье разработаны командами профессионалов, проверены временем и сотнями миллионами пользователей (а также большим количеством хакеров), хоть и никаких гарантий, что именно данный вариант реализации — абсолютно правильный и 100% безопасный, конечно же нет. Информация основана на личном анализе этих ресурсов.
Читать дальше →
Total votes 83: ↑71 and ↓12 +59
Comments 30

Знакомство с Go, часть 2: пишем граббер изображений с балансировщиком и извращениями

Reading time 13 min
Views 23K

Задание


Недавно я рассказывал, как выполнял секретную миссию и с помощью Go загружал дамп цитат с «пустоты». Пришло время снова вступить в бой, на этот раз дело касается «Ататы», и не только потому что в рифму с пустотой.

Для тех кто пропустил — в свое время «Тематические Медиа» (да-да, хозяева хабра) запустили проект «Респектива» ( этакую гламурную имиджборду\тумблр с одним разделом), хитроумными баннерами заманили туда девушек и программистов и стали ждать, видимо надеясь что срастется. Не срослось, и через некоторое время «Респективу» мутировали в «Атату», которая уже имела функционал для создания пользовательских бордпотоков, хабов для объединения тематических потоков и так далее. Какое-то время проект развивался, но Девушки ушли, остались программисты, да и их стало куда меньше. Сейчас это место почти покинуто, там чумные ветра, брошенные поезда, темнота и только редкие вопли нескольких выживших старожилов изредка прорезают хтмл в ночи.

И ладно, атата с ней, с этой ататой. Но отличного контента в виде картинок там осталось немало, один тред с обоями чего стоит! Поэтому неудивительно, что следующее задание из штаба выглядело следующим образом:
«Срочно сохранить для потомков все изображения из потока #949 #291. ps. Извращенно.»

Ну, что же, есть задание — нужно работать. Вообще-то по извращенным структурам у нас уже есть некий кофейный чемпион, но и на Go тоже можно что-нибудь сообразить! После 9 часов работы в Paint у меня родился следующий план атаки:



Степень изврата поражает, начальство будет довольно! Рассмотрим что тут и как:

«Генератор» будет загружать с ататы хтмл код страниц, выдергивать урлы картинок и передавать их «Балансировщику», который раскидывает эти урлы некоторому количеству «Рабочих» (каждый из которых имеет свою небольшую очередь заданий) следя за тем, чтобы все рабочие были равномерно нагружены. Ну а «рабочие» загружают картинки и радуют глаз умиленного балансировщика. Выглядит избыточно, но зато про войну! Поехали:
Читать дальше →
Total votes 50: ↑49 and ↓1 +48
Comments 11

Знакомство с Go — пишем граббер веб страниц с многопоточностью и блудницами

Reading time 11 min
Views 70K
Про язык Go от команды Google слышали, наверное, все. А вот пробовали далеко не все, и очень зря — общение с сусликами Go это море удовольствия, в чем я недавно убедился на собственном опыте.
Начинать знакомство с новым языком забавнее всего на жизненном примере, поэтому я, не долго думая, взял первую попавшуюся задачу “из жизни, самой первостепенной важности”:

Есть в интернете сайт http://vpustotu.ru на котором любой желающий может анонимно высказаться о наболевшем. Все высказывания (в дальнейшем буду называть их “цитатами”) сначала попадают в модерацию (аналог “бездны” башорга), где посетители могут оценить полет мысли и проголосовать за цитату в стиле “Ого!” или “Ерунда!”. На странице модерации (http://vpustotu.ru/moderation/) нам показывают случайную цитату, ссылки голосования и ссылку “Еще”, которая ведет на эту же страницу. Пощелкайте, это все очень просто.

И вот возникла задача – срочно, под покровом темноты, загрузить себе полный дамп всех цитат на модерации для дальнейшего секретного исследования. Не будем оценивать житейскую ценность и степень идиотизма задачи, а рассмотрим её с технической точки зрения:

В разделе модерации нет прямых ссылок на определенную цитату, единственный способ получить новую цитату – обновить страницу (или перейти по ссылке “еще”, что одно и тоже). Причем вполне возможны повторы, что легко обнаруживается после пары минут агрессивного кликинга.

Таким образом нужна программа, которая:

  • Должна последовательно обновлять и парсить (разбирать) страницу, записывая цитату.
  • Должна уметь отбрасывать дубликаты.


Логично, что мы понятия не имеем все ли цитаты загружены, но об этом можно косвенно догадаться по большому количеству повторно полученных цитат подряд. Поэтому дополним:

  • Должна останавливаться не только по команде, но и по достижению определенного числа “повторов”, например 500!
  • Так как это, скорее всего, займет некоторое время: необходимо уметь продолжить “с места на котором остановились” после закрытия.
  • Ну и раз уж все-таки это надолго – пусть делает свое грязное дело в несколько потоков. Хорошо-бы в целых 4 потока (или даже 5!).
  • И отчитывается об успехах в консоль каждые, скажем, 10 секунд.
  • А все эти параметры пускай принимает из аргументов командной строки!


Ну, вроде все понятно. Пусть программа ведет два файла – с цитатами и с некими хешами этих цитат, чтобы не повторяться, и перечитывает файл в начале каждого запуска. Ну а дальше в цикле разбирает страницу, выдергивая все новые и новые откровения, пока не получит ctrl-c по лбу или же не встретит определенное количество повторов. Задача ясна, план есть – поехали!
Читать дальше →
Total votes 78: ↑74 and ↓4 +70
Comments 30

Evercookie — самые устойчивые куки

Reading time 1 min
Views 73K
Samy Mamkar разработал систему, которая позволяет хранить куки в 8 местах, автоматически восстанавливая друг друга, и даже добиться того, чтобы куки, поставленное в одном браузере, действовало и в другом.

Удалить это куки практически невозможно! (Все возможно, конечно, но слишком много мороки)

Куки хранятся в:
  • HTTP Cookies;
  • Local Shared Objects (Flash);
  • Сохранение куки в значениях RGB автосгенерированных и форсированно кэшированных PNG с использованием HTML5 canvas;
  • Сохранение куки в Web History;
  • HTML5 Session Storage;
  • HTML5 Local Storage;
  • HTML5 Global Storage;
  • HTML5 Database Storage через SQLite.

При удалении из одного из этих мест кука автоматически восстанавливается из оставшихся. Работает даже если пользователь сменит браузер (через Local Shared Objects из Flash).

Описание (на английском) и демо: http://samy.pl/evercookie/.
Попробуйте удалить куки, почистить систему и зайти назад.



Как пользоваться?
Читать дальше →
Total votes 111: ↑107 and ↓4 +103
Comments 68

Вникаем в метаклассы Ruby

Reading time 6 min
Views 52K

Примечание переводчика: данный пост является логическим развитием, а точнее «предысторией» поста Вникаем в include и extend и был подсказан в комментариях к нему пользователем murr, за что ему большое спасибо.

Классы и объекты в Ruby связаны между собой достаточно затейливо и не сразу можно понять что к чему. Из-за особого назначения классов очень легко потерять из вида тот факт, что классы — это тоже объекты Ruby. От «обычных» объектов их отличает два вещи: они служат образцом для создания новых объектов и они являются частью иерархии классов. Все верно, классы могут иметь экземпляры себя (объекты), суперклассы (родителей) и подклассы (детей).

Если классы — это объекты, то у них должен быть свой собственный класс. Классом всех классов (как объектов) в Ruby является класс Class:

# один из способов создать новый класс
Dog = Class.new
    
# общепринятый способ создания класса
class Dog
    # какая-то реализация собачьего поведения
end

Dog.class
=> Class

Читать дальше →
Total votes 41: ↑39 and ↓2 +37
Comments 11

Разработка web API

Reading time 9 min
Views 287K

Интро


Это краткий перевод основных тезисов из брошюры «Web API Design. Crafting Interfaces that Developers Love» Брайана Маллоя из компании Apigee Labs. Apigee занимается разработкой различных API-сервисов и консталтингом. Кстати, среди клиентов этой компании засветились такие гиганты, как Best Buy, Cisco, Dell и Ebay.

В тексте попадаются комментарии переводчика, они выделены курсивом.

Собираем API-интерфейсы, которые понравятся другим разработчикам


Понятные URL для вызовов API

Первый принцип хорошего REST-дизайна — делать вещи понятно и просто. Начинать стоит с основных URL адресов для ваших вызовов API.

Ваши адреса вызовов должны быть понятными даже без документации. Для этого возьмите себе за правило описывать любую сущность с помощью коротких и ясных базовых URL адресов, содержащих максимум 2 параметра. Вот отличный пример:
/dogs для работы со списком собак
/dogs/12345 для работы с отдельной собакой
Дальше
Total votes 235: ↑224 and ↓11 +213
Comments 128

Нужны ли в JavaScript классы?

Reading time 6 min
Views 104K
JavaScript принято считать прототип-ориентированным языком программирования. Но, как ни странно, этим подходом практически никто не пользуется: большинство популярных JS-фреймворков явно или неявно оперируют классами.
В этой статье я хочу рассказать об альтернативном способе программирования на JavaScript, без использования классов и конструкторов — чистым прототипным ООП и особенностях его реализации на ECMA Script 5.
Читать дальше →
Total votes 164: ↑140 and ↓24 +116
Comments 60

Диаграммы в LaTeX

Reading time 12 min
Views 26K
Многие достаточно часто сталкиваются с необходимостью создания различных диаграмм, графов, деревьев для удобного представления информации. Особенно важным этот вопрос может оказаться при создании презентаций. Большинство офисных пакетов предоставляют возможность создавать красивые диаграммы при помощи интерактивного интерфейса. А если нужно создать большую диаграмму? Или записать в ней математические формулы? Сосредоточиться на содержании, а не оформлении и расположении элементов на экране?

Преимущества использования LaTeX уже неоднократно обсуждались. Так же как и способы создания презентаций при помощи beamer и векторная графика из пакета PGF/Tikz. Но возможно ли получить в LaTeX диаграммы, не уступающие по внешнему виду полученным в больших и сложных пакетах? Один из способов предложен ниже.
Читать дальше →
Total votes 61: ↑58 and ↓3 +55
Comments 17

Зачем Google добавляет while(1); к своим JSON-ответам?

Reading time 2 min
Views 68K
Это позволяет избежать CSRF/XSRF-атак (подделки межсайтовых запросов).

Рассмотрим следующий пример: допустим у Google есть URL вида gmail.com/json?action=inbox, который возвращает 50 первых сообщений вашего почтового ящика в формате JSON. Злоумышленник, чей сайт находятся на другом домене, не может выполнить AJAX запрос, обратившись по данному URL, чтобы получить данные, ввиду same origin policy (правило ограничения домена). Но ничто не мешает злоумышленнику включить вышеуказанный URL на свою страницу с помощью тега .
Читать дальше →
Total votes 187: ↑175 and ↓12 +163
Comments 145

Rails params & GC

Reading time 2 min
Views 6.3K
У нас тут в Rails комьюнити опять драма. Первоначальный репорт. Есть методы типа find_by_* которые проецируются на модели в find_by_title например и find_by_id.
Их можно использовать так
find_by_id(params[:id], select: «CUSTOM SQL»)
Но обычно их используют вот так
find_by_id(params[:id])
И происходит SQL Injection если в params[:id] лежит {:select => «CUSTOM SQL»} — опции могут быть и в первом аргументе.

Обратите внимание — :select это символ а не «select»(строка). Это значит что трюк ?id[select]=SQL не пройдет т.к. ключ окажется строкой. И вообще params это хеш типа HashWithIndifferentAccess. Те у него ВПРИНЦИПЕ не может быть символов в ключах т.к. они все уничтожаются при создании.

Есть такой gem authlogic, в общем виде он использует find_by_token(token) где token это объект из сессии(которая хранится в куках и подписана session_secret). Чтобы в него записать :select => «SQL» вам нужно знать session_secret, поэтому уязвимость крайне редкая.
Весь этот SQL Injection CVE не стоит выеденного яйца! И ради чего пост? DoS!
Читать дальше →
Total votes 54: ↑42 and ↓12 +30
Comments 20

Как устроен jQuery: изучаем исходники

Reading time 6 min
Views 57K

jQuery однозначно стал стандартом в индустрии веб-дева. Есть много отличных js-фреймворков, которые заслуживают внимания, но jQuery поразил всех своей лёгкостью, изящностью, магией. Люди пишут с использованием jQuery, люди пишут плагины для jQuery, люди даже пишут статьи про jQuery, но мало кто знает (особенно из новичков), КАК устроен jQuery.

В этой статье проведем небольшой экскурс во внутренности этого фреймворка и разберем, что внутри.
Статья рассчитана на базовые знания Javascript. Задумайтесь и, если вы знаете, как написать клон jQuery, то, скорее всего, вы тут не найдёте ничего нового. Остальным — добро пожаловать под кат

Читать дальше →
Total votes 212: ↑200 and ↓12 +188
Comments 40

jQuery изнутри — введение

Reading time 6 min
Views 102K
По работе мне несколько раз приходилось участвовать в собеседовании кандидатов на должность клиент-сайдера у нас в компании, смотреть на их познания в Javascript. Удивительно что никто из них не знал толком как же работает jQuery изнутри, даже те, кто отметил свои знания jQuery уровнем «отлично», увы.

У jQuery очень низкий порог вхождения, о нем часто пишут и используют всюду, где только можно (и даже там, где, в общем-то, не нужно), поэтому некоторые даже не смотрят на чистый Javascript. Зачем, мол, его знать, когда есть jQuery, а по нему — тонны примеров и готовых плагинов? Даже на Хабре видел статью про рисование на Canvas, где автор подключил jQuery и использовал его только один раз — для того, чтобы получить доступ к Canvas по его идентификатору. И не считал это чем-то ненормальным.

Извините, отвлекся. Суть поста и следующих частей серии в том, чтобы рассказать о том, как же работает библиотека изнутри и что же в ней происходит по мере выполнения каких-то методов.
Готов и хочу читать дальше
Total votes 149: ↑139 and ↓10 +129
Comments 80

Что почитать, чтобы повысить свой уровень JavaScript

Reading time 3 min
Views 98K
От переводчика: Я думаю многие читали статью Rey Bango — What to Read to Get Up to Speed in JavaScript, но до хабра обсуждение так и не докатилось. Предлагаю закрыть этот пробел и поговорить о хороших книгах, блогах, тренингах и конференциях, посвященных в первую очередь клиентскому JavaScript и клиентской веб-разработке. Чтобы не копипастить оформляю статью в виде перевода.

Сейчас в рассылке JSMentors JavaScript идет обсуждение книг, который стоит прочитать, чтобы улучшить свои знания. Там было много позитивных отзывов и предложений. Я хочу показать вам те книги и интернет-ресурсы, который я считаю важными и которые помогут вам в обучении. На этой странице я перечислил большое количество источников, разделенных по уровням.

Учтите, что некоторый ресурсы могут принадлежать нескольким уровням и охватывают широкие аспекты языка. Если вы считаете, что я что-то упустил, пожалуйста, дополните меня в комментариях.

Не заставляю вас читать все книги, которые предложены ниже. Эти книги я читал на протяжении многих лет и почерпнул в каждой много полезного. Я их распределяю по категориям, чтобы вам было проще работать с ними. Выберите книги, которые подходят вам.
Читать дальше →
Total votes 165: ↑161 and ↓4 +157
Comments 31

Оптимизируем производительность JavaScript для V8

Reading time 6 min
Views 27K

Предисловие


Дэниел Клиффорд сделал на Google I/O прекрасный доклад, посвященный особенностям оптимизации кода JavaSсript для движка V8. Дэниел призвал нас стремиться к большей скорости, тщательно анализировать отличия между С++ и JavaScript, и писать код, помня о том, как работает интерпретатор. Я собрал в этой статье резюме самых главных моментов выступления Дэниела, и буду обновлять её по мере того, как движок будет меняться.
Читать дальше →
Total votes 75: ↑73 and ↓2 +71
Comments 62

Про jQuery и велосипеды — мое дополнение

Reading time 6 min
Views 64K
Сразу спешу сообщить вам, что я никоим образом не связан с автором предыдущей статьи. Однако, прочитав ее и увидев такой положительный отклик сообщества на статью, я тоже вдохновился и решил добавить немного своих наблюдений и знаний, к тому же это может послужить моей входной точкой в круги хабрасообщества.

Для затравки начнем с простого.
Читать дальше →
Total votes 242: ↑230 and ↓12 +218
Comments 126
1

Information

Rating
Does not participate
Registered
Activity