DNS безалаберность Вконтакте и других компаний

Как известно, система DNS в сети Интернет является одной из ключевых. Без неё невозможно представить современное состояние сети.

Любая ошибка в публикации DNS записей или даже кратковременная неработоспособность этого сервиса может привести к весьма печальным результатам, например потери трафика от пользователей. С другой стороны DNS исключительно хорошо масштабируется и толерантен к сбоям единичных серверов.
DNS важен, профессионалы это понимают. И несмотря на это ошибки в управлении им встречаются даже у самых больших компаний. И не замечаются ими, пока не приводят к существенным проблемам.

Например, список DNS ошибок у не требующей представления компании Вконтакте:
У регистратора vk.com указаны следующие список авторитативных серверов домена:
- ns1.vkontakte.ru
- ns2.vkontakte.ru
- ns3.vkontakte.ru
- ns4.vkontakte.ru

На самих авторитативных серверах Вконтакте указан следующий список:
- ns1.vkontakte.ru
- ns2.vkontakte.ru
- ns4.vkontakte.ru

Он отличается от списка у регистратора!

Более того сервер ns2.vkontakte.ru [93.186.224.100] не отвечает на запросы, по крайней мере уже несколько дней.

Ошибка Skype и Microsoft:
В ответах на запросы к cloudapp.net не возвращается Authority Section.
В частности в ответе на тип запроса “AAAA” к skypeecs-prod-euw-0-b.cloudapp.net. Из за этого негативный ответ на такой запрос нельзя кешировать, так как непонятно насколько по времени это можно сделать, если строго соблюдать RFC.

Ошибка Twitter и Dyn:
В ответах на запросы к platform.twitter.com при типе запросов NS сервера Dyn, обслуживающие Twitter отвечают что такой записи не существует. При этом на любой другой тип запросов к этому же имени они отвечают записью CNAME.
Соответственно, если у нас уже закеширован этот ответ на тип запроса NS то, если строго соблюдать стандарты RFC, мы не можем закешировать CNAME в ответе к этому же имени для других типов запросов. Собственно в этом случае поведение кеширующего рекурсивного сервера не детерминировано по стандартам и отдано на откуп собственной логике программиста.

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

Все опубликованные ошибки были актуальны на 7 Мая 2016. В тот момент когда вы будете читать эту статью их может уже не быть.

ссылка на оригинал статьи https://habrahabr.ru/post/283116/

Как использовать API сайта, когда его нет

В этой статье мы разберем, как получить и использовать API сайта, если по нему нет документации или оно еще не открыто официально. Руководство написано для новичков, которые еще не пробовали зареверсить простой API. Для тех же кто сам занимался подобным ничего нового здесь нет.

Разбор проведем на примере API сервиса https://www.captionbot.ai/ который недавно открыл Microsoft (спасибо им за это). Многие могли прочитать о нем в статье на Geektimes. Сайт использует ajax запросы в формате JSON, поэтому скопировать их будет легко и приятно. Поехали!

КДПВ

Анализируем запросы

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

image

В нашем случае все интересующие нас запросы имеют базовый URL https://www.captionbot.ai/api

Инициализация

При первом открытии сайта идет GET запрос на /api/init без параметров.
Ответ имеет Content-Type: application/json, при этом в теле ответа нам приходит просто строка вида:

"54cER5HILuE"

Запомним это и идем дальше.

Отправка URL

У нас есть два способа загрузить изображение: через URL и через загрузку файла. Для теста берем URL изображения Лены с вики и отсылаем. В сетевой активности появляется POST запрос на /api/message со следующими параметрами:

{     "conversationId": "54cER5HILuE",     "waterMark": "",     "userMessage": "https://upload.wikimedia.org/wikipedia/ru/2/24/Lenna.png" }

Ага, говорим себе мы, значит метод init вернул нам строку для conversationId, а в userMessage попала наша ссылка. Что такое waterMark пока непонятно. Смотрим на данные ответа:

"{\"ConversationId\":null,\"WaterMark\":\"131071012038902294\",\"UserMessage\":\"I am not really confident, but I think it's a woman wearing a hat\\nand she seems . \",\"Status\":null}"

Зачем-то закодировали JSON дважды, ну да ладно. В человеческом виде это выглядит так:

{     "ConversationId": null,     "WaterMark": "131071012038902294",     "UserMessage": "I am not really confident, but I think it's a woman wearing a hat\\nand she seems .",     "Status": null }

Все параметры по пути поменяли манеру написания, но это мелочи жизни. Итак, нам вернули некоторое значение WaterMark, почему-то пустой ConversationId, собственно подпись к фото в поле UserMessage и некий пустой статус.

Загрузка изображения

Далее, не закрывая вкладку, пробуем ту же операцию с загрузкой фото из локального файла. Видим POST запрос на /api/upload в формате multipart/form-data с названием поля file:

-----------------------------50022246920687 Content-Disposition: form-data; name="file"; filename="Lenna.png" Content-Type: image/png

В ответ получаем строку URL нашего загруженного файла, можем перейти по нему и убедиться в этом:

"https://captionbot.blob.core.windows.net/images-container/2ogw3q4m.png"

Затем отсылается уже знакомый нам запрос на /api/message:

{     "conversationId": "54cER5HILuE",     "waterMark": "131071012038902294",     "userMessage": "https://captionbot.blob.core.windows.net/images-container/2ogw3q4m.png" }

Вот и пригодился waterMark из предыдущего ответа, а URL тот, что нам вернул метод upload. Данные ответа аналогичны предыдущим.

Пишем обертку

Чтобы использовать полученные знания с удобством, делаем простую обертку на вашем любимом языке программирования. Я сделаю это на Python. Для запросов к сайту использую requests, так как он удобный и в нем есть сессии, которые хранят cookie за меня. Сайт использует SSL, но по дефолту requests будет ругаться на сертификат:

hostname 'www.captionbot.ai' doesn't match either of '*.azurewebsites.net', '*.scm.azurewebsites.net', '*.azure-mobile.net', '*.scm.azure-mobile.net'

Решается это установкой флага verify=False при каждом запросе.

Полный исходник

import json import mimetypes import os import requests import logging logger = logging.getLogger("captionbot")  class CaptionBot:     BASE_URL = "https://www.captionbot.ai/api/"      def __init__(self):         self.session = requests.Session()         url = self.BASE_URL + "init"         resp = self.session.get(url, verify=False)         logger.debug("init: {}".format(resp))         self.conversation_id = json.loads(resp.text)         self.watermark = ''      def _upload(self, filename):         url = self.BASE_URL + "upload"         mime = mimetypes.guess_type(filename)[0]         name = os.path.basename(filename)         files = {'file': (name, open(filename, 'rb'), mime)}         resp = self.session.post(url, files=files, verify=False)         logger.debug("upload: {}".format(resp))         return json.loads(resp.text)      def url_caption(self, image_url):         data = json.dumps({             "userMessage": image_url,             "conversationId": self.conversation_id,             "waterMark": self.watermark         })         headers = {             "Content-Type": "application/json"         }         url = self.BASE_URL + "message"         resp = self.session.post(url, data=data, headers=headers, verify=False)         logger.debug("url_caption: {}".format(resp))         if not resp.ok:             return None         res = json.loads(json.loads(resp.text))         self.watermark = res.get("WaterMark")         return res.get("UserMessage")      def file_caption(self, filename):         upload_filename = self._upload(filename)         return self.url_caption(upload_filename)

Исходный код есть на Github, плюс готовый пакет в pip.

ссылка на оригинал статьи https://habrahabr.ru/post/283112/

Как отключить инъекцию скрипта ff.kis.scr.kaspersky-labs.com при использовании Kaspersky Internet Security 2016

Если у вас установлен антивирус Kaspersky Internet Security 2016, вы, вероятно, неоднократно сталкивались с инъекцией скрипта ff.kis.scr.kaspersky-labs.com/USER_ID/main.js в код страниц браузера. Если для рядового пользователя ничего страшного в этом, наверное, нет, то для веб-разработчика приятного мало: инородный скрипт в теле с траниц раздражает, а главное, постоянными запросами забивает мониторинг сети.

image

Самое плохое в этой ситуации — невозможность отключить инъекцию в настройках текущей версии программы. Никак. Форум тех. поддержки компании забит вопросами на эту тему.

К счастью, настройка убирающая скрипт появилась в Maintenance Release 1 (версия 16.0.1.445). Эту версию в данный пока невозможно момент скачать со стандартной страницы с дистрибутивами, однако, она доступна на ftp сервере.

Важно! Обратите внимание, что MR 1 пока не рекомендуется к установке из-за проблем, описанных здесь. Прочтите, пожалуйста, написанное там внимательно, прежде чем обновляться. Особенно это касается тех, кто использует IE.

Я понял, что с новой версией есть проблемы, но всё равно хочу её установить

Если вы всё таки решились установить MR 1, то возможность отключить инъекцию у вас появится: Идём в настройки -> «Дополнительно» -> «Сеть» -> «Внедрять в трафик скрипт для взаимодействия с веб-страницами». Эту галочку, которой не было в версии 16.0.0, нужно снять.

image

После перезапуска браузера, инородный скрипт пропадёт.

ссылка на оригинал статьи https://habrahabr.ru/post/283110/

Scrum. Взгляд программиста

Всем привет, за 15 лет работы программистом мне довелось поработать в разных командах, но работа в одной из них мне запомнилась больше всего. Наш тимлидер был поклонник методологии Scrum и к тому же большой затейник. В этой статье я расскажу как были организованы процессы в команде и что из этого вышло.

О методологии Scrum

Scrum является одной из разновидностей гибких методологий Agile и позволяет быстро реагировать на изменяющиеся внешние требования. В Scrum основными понятиями являются итерация и спринт. Весь рабочий процесс разбивается на временные отрезки, которые называются итерация. В итерацию входит планирование, непосредственная разработка (спринт) и тестирование. Итерация имеет жесткие временные ограничения. Таким образом, Scrum ориентирован в первую очередь на сроки выполнения задач.

О процессе

Давайте теперь рассмотрим как именно был реализован Scrum внутри нашей команды. Сначала мы окинем весь процесс общим взглядом, а потом рассмотрим каждый этап подробно. Каждая итерация у нас длилась один месяц. Начиналась она с планирования и оценки задач, затем шел спринт, во время которого проводились ежедневные пятиминутки и прочие митинги по необходимости. По окончанию разработки была демонстрация нового функционала и ретроспектива.

Планирование

Все начиналось с того, что Product manager создавал список задач на основе целей продукта и отзывов пользователей. Затем из этого списка он выбирал первоочередные задачи и отдавал нам на оценку. Этот список был немного больше, чем мы реально могли сделать за месяц на тот случай если вдруг случится чудо. Мы много жаловались на то, что в задачах не было прописано всё до мелочей. Но сейчас, я могу сказать точно, что ни в одной другой команде я еще не видел такого качественного оформления задач от PM.

Далее, команде предстояло оценить каждую задачу и по оценкам понять, что войдет в предстоящий спринт. Про оценивание надо рассказать подробнее. На первых этапах оценивали так: тимлидер назначал каждую задачу на каждого разработчика и разработчик давал оценку. Если оценка разработчика сильно отличалась от ожиданий, то пытались разобраться в причине расхождений и корректировали либо оценку либо задачу. Это занимало много времени у тимлидера, а он всегда стремился сделать систему самостоятельной, что привело в итоге к использованию Planning-poker’а. Каждый разработчик оценивал все задачи команды на предстоящий спринт, а затем тимлидер вычислял среднюю оценку на каждую задачу. Минусом такого подхода было то, что оценку давали разработчики разных уровней и если потом задача попадала новичку, то конечно он делал задачу дольше этой оценки. Пытались вводить коэффициенты по каждому разработчику, но это еще больше все усложняло. В итоге, потом, с приходом новой системы стимулирования вообще отказались от индивидуальной оценки задач, но об будет чуть ниже.

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

Пятиминутка

Процесс разработки был самым длительным в итерации. В это время ежедневно по утрам проводилась пятиминутка. У нас он назывался stand up митинг. Все вставали в кружок и каждый рассказывал, что он делал вчера и что собирается делать сегодня.

Целью этого митинга была синхронизация задач между участниками команды и выявление возникших проблем. Помимо этого был еще психологический момент. Если человек утром давал обещание перед командой что-то сделать, то ему уже труднее было не сдержать это обещание. У участников команды было очень разное отношение к этому митингу. Были так называемые “солдаты” — люди, которые понимали суть митинга, приходили и по-солдатски докладывали обстановку. Были и “бунтари” — люди, которые никак не хотели отрываться от мониторов и стоять в круге со всеми. Но большинство относилось к этому спокойно, как к части работы.

Спринт

Интересной особенностью нашей разработки было то, что наш тимлидер был категорически против разделения на специальности. То есть программист должен был уметь сделать любую задачу или починить баг за другим программистом. Этот подход достаточно спорный и если хотите — его можно обсудить в комментариях…

В качестве планировщика задач мы использовали систему Target Process. По началу у нас не было настоящей доски, только список задач в этой системе. Позже появилась доска, но она не была центральной частью процесса и пятиминутные митинги не строились вокруг нее. Скорее это было просто визуальное представление, где находится задача на отрезке спринта.

Поскольку тимлидеру надо было как-то отслеживать успевает программист внутри своей задачи или нет, то у нас была практика отчетов о потраченном времени на каждую задачу и помимо этого, каждый день программист должен был обновлять у задачи оценку — сколько времени по его мнению осталось потратить на эту задачу.

На основе этих данных руководство строило burndown диаграммы, по которым можно было увидеть успеваем мы или нет.

Ревью кода мы проводили в специальной программе Code Collaborator. При отправке кода на ревью можно было назначить только одного ревьюера и любое количество обозревателей. Только ревьюер решал можно коммитить данный код или нет. Комментарии обозревателей носили только рекомендательный характер. Интересно, что если член команды не был в списке обозревателей и ревьюеров, то он даже посмотреть не мог этот код.

Демо

После того, как все задачи были сделаны и протестированы наступало время митинга под названием “Демо”. На этом митинге собирались все участники команды от дизайнеров до отдела технической документации и смотрели выступления разработчиков.

Каждый разработчик на большом экране показывал, что он сделал за текущий спринт. Особенно эффектно это выглядело у frontend разработчиков, но и backend разработчики открывали на экран консоль и показывали новый крутой API запрос.

Польза от этого митинга в том, что во время пятиминуток обычно люди рассказывают, что они что-то делают, но потом редко кто-то из команды видит результат, так как каждый варится в своем наборе задач. Так вот, демо — это хороший шанс узнать, что нового появляется в продукте. Демо поднимает общий боевой дух и дает ощущение, что наш корабль плывет, а не стоит на месте.

А еще есть и побочный эффект. Нередко бывало такое, что во время демо случались казусы и что-то шло не так или придумывались новые интересные кейсы поведения и поэтому команда тестирования всегда уходила с полным блокнотиком багов.

Ретроспектива

Ретроспектива — это митинг, который проводится после завершения итерации с целью выявить текущие проблемы и улучшить процесс на будущее. В нашей команде этот митинг назывался Post mortem. Наш тимлидер хотел, чтобы этот митинг проходил в максимально расслабленной атмосфере, поэтому мы покупали пиво и закуску, садились за стол, отмечали окончание итерации и заодно обсуждали кому что понравилось в прошедшей итерации и что не понравилось. Равнодушных в команде почти не было, поэтому это застолье обычно было очень жарким и долгим. Product manager жаловался на программистов, что задачи не сделаны в срок, тестировщики жаловались на программистов, что слишком поздно отдаются задачи в тестирование и они не успевают их проверить до окончания итерации. А программисты жаловались, что задачи приходят не продуманными и приходится много времени тратить на продумывание специфических ситуаций.

В какой-то момент мы заметили, что на каждой ретроспективе жалуемся на одно и то же и решили записывать все моменты. Потом мы поняли, что на каждой ретроспективе мы записываем одно и тоже. Тогда мы решили не просто записывать, а назначать решение каждой проблемы на конкретного человека и он на следующей ретроспективе должен был отчитаться. Потом мы поняли, что пока все отчитаются, пока запишут новые проблемы — времени выпить уже не остается и решили отделить ретроспективу от пьянки. После этого стало уже не так интересно и ретроспектива превратилась в сухой неинтересный митинг.

От себя могу отметить, что ретроспектива помимо своего основного значения несет очень важный момент — психологическую разрядку. Это время, когда человек совершенно безнаказанно может высказать все, что у него накопилось за месяц и продолжить спокойно работать. Несмотря на явную агрессию во время митинга, после его окончания команда становилась каждый раз еще более сплоченной.

Прочие мероприятия

Еще у нас был митинг “one and one”. Раз в две недели тимлидер разговаривал с каждым членом команды, где тот мог сказать всё то, что нельзя сказать на ретроспективе.
Были и неофициальные мероприятия за пределами офиса. Например два раза в год мы ездили командой на шашлыки.

Стимулирование

В жизни любой команды есть
ссылка на оригинал статьи https://megamozg.ru/post/26086/

Энтузиаст изготовил модель радиального двигателя из дерева и пластика

image

Если вы любите двигатели, но вам больше нравится работать с деревом – всё в ваших руках. Энтузиаст Иен Джиммерсон [Ian Jimmerson] решил совместить свои хобби, и изготовил модель радиального двигателя в натуральную величину. Почти все части двигателя выполнены из дерева, цилиндры же для наглядности сделаны из прозрачного пластика.

На изготовление модели у энтузиаста ушло два года, как он сам говорит, работы «по ночам и в выходные». На 9-минутном видео Джиммерсон подробно рассказывает принципы и схему работы 9-поршневого радиального двигателя

.

Джиммерсона вдохновили на создание модели валявшиеся без дела трубы из прозрачного пластика. Он внезапно решил совместить свою любовь к двигателям с увлечением работой с деревом. Взяться за реализацию довольно сложной схемы радиального двигателя ему также подсказало его давнее увлечение этим типом двигателей.

Иен вскоре обнаружил, что хотя в интернете можно найти довольно много разных анимаций, посвящённых радиальным двигателям, практически невозможно найти подробные объяснения того, как они работают. После того, как он сам подробно разобрался во всём, ему захотелось сделать видеоролик, в котором он рассказывал бы всем интересующимся об этом двигателе.

Иен объясняет, что радиальные двигатели с одним рядом цилиндров всегда изготавливаются с нечётным их количеством, из-за принципа работы зажигания. Однако существуют версии с несколькими рядами цилиндров, количество которых может достигать 14, 18 или даже 28 – таким был гигантский двигатель Pratt & Whitney R-4360 Wasp Major, созданный во время Второй Мировой войны. Это был крупнейший двигатель, производившийся в США серийно.

image
Pratt & Whitney R-4360 Wasp Major

ссылка на оригинал статьи https://geektimes.ru/post/275468/