Posts de December, 2010

[Francisco Souza] Killer Java applications server with nginx and memcached

Sunday, December 12th, 2010

Last days I worked setting up a new web serving structure for Wine, the largest wine’s e-commerce in Latin America. After testing, studying and learning a lot, we built a nice solution based on nginx and memcached. I will use a picture to describe the architecture:

As you can see, when a client do a request to the nginx server, it first checks on memcached if the response is already cached. If the response was not found on cache server, then nginx forward the request to Tomcat, which process the request, cache the response on memcached and returns it to nginx. Tomcat works only for the first client, and all other clients requesting the same resource will get the cached response on RAM. My objective with this post is to show how we built this architecture.

nginx

nginx was compiled following Linode instructions for nginx installation from source. The only difference is that we added the nginx memcached module. So, first I downloaded the memc_module source from Github and then built nginx with it. Here is the commands for compiling nginx with memcached module:

% ./configure --prefix=/opt/nginx --user=nginx --group=nginx --with-http_ssl_module --add-module={your memc_module source path}% make% sudo make install

After install nginx and create an init script for it, we can work on its settings for integration with Tomcat. Just for working with separate settings, we changed the nginx.conf file (located in /opt/nginx/conf directory), and it now looks like this:

user  nginx;worker_processes  1;

error_log  logs/error.log;

events {    worker_connections  1024;}

http {    include       mime.types;    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                                '$status $body_bytes_sent "$http_referer" '                                '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;    #tcp_nopush     on;

    #keepalive_timeout  0;    keepalive_timeout  65;

    #gzip  on;

    include /opt/nginx/sites-enabled/*;}

See the last line inside http section: this line tells nginx to include all settings present in the /opt/nginx/sites-enabled directory. So, now, let’s create a default file in this directory, with this content:

server {    listen       80;    server_name  localhost;

    default_type  text/html;

    location / {        proxy_set_header    X-Real-IP   $remote_addr;        proxy_set_header    Host        $http_host;        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;

        if ($request_method = POST) {            proxy_pass      http://localhost:8080;            break;        }

        set $memcached_key   "$uri";        memcached_pass      127.0.0.1:11211;

        error_page  501 404 502 = /fallback$uri;    }

    location /fallback/ {        internal;    

        proxy_set_header    X-Real-IP   $remote_addr;        proxy_set_header    Host        $http_host;        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_redirect      off;

        proxy_pass          http://localhost:8080;    }

}

Some stuffs must be explained here: the default_type directive is necessary for proper serving of cached responses (if you are cache other content types like application/json or application/xml, you should take a look at nginx documentation and deal conditionally with content types). The location / scope defines some settings for proxy, like IP and host. We just did it because we need to pass the right information to our backend (Tomcat or memcached). See more about proxy_set_header at nginx documentation. After that, there is a simple verification oF the request method. We don’t want to cache POST requests.

Now we get the magic: first we set the $memcached_key and then we use the memcached_pass directive, the $memcached_key is the URI. memcached_pass is very similar to proxy_pass, nginx “proxies” the request to memcached, so we can get some HTTP status code, like 200, 404 or 502. We define error handlers for two status codes:

  • 404: memcached module returns a 404 error when the key is not on memcached server;
  • 502: memcached module returns a 502 error when it can’t found memcached server.

So, when nginx gets any of those errors, it should forward the request to Tomcat, creating another proxy. We configured it out on fallback, an internal location that builds a proxy between nginx and Tomcat (listening on port 8080). Everything is set up with nginx. As you can see in the picture or in the nginx configuration file, nginx doesn’t write anything to memcached, it only reads from memcached. The application should write to memcached. Let’s do it.

Java application

Now is the time to write some code. I chose an application written by a friend of mine. It’s a very simple CRUD of users, built by Washington Botelho with the goal of introducing VRaptor, a powerful and fast development focused web framework. Washington also wrote a blog post explaining the application, if you don’t know VRaptor or want to know how the application was built, check the blog post “Getting started with VRaptor 3″. I forked the application, made some minor changes and added a magic filter for caching. All Java code that I want to show here is the filter code:

package com.franciscosouza.memcached.filter;

import java.io.IOException;import java.io.PrintWriter;import java.io.StringWriter;import java.net.InetSocketAddress;

import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;

import net.spy.memcached.MemcachedClient;

/** * Servlet Filter implementation class MemcachedFilter */public class MemcachedFilter implements Filter {

    private MemcachedClient mmc;

    static class MemcachedHttpServletResponseWrapper extends HttpServletResponseWrapper {

        private StringWriter sw = new StringWriter();

        public MemcachedHttpServletResponseWrapper(HttpServletResponse response) {            super(response);        }

        public PrintWriter getWriter() throws IOException {            return new PrintWriter(sw);        }

        public ServletOutputStream getOutputStream() throws IOException {            throw new UnsupportedOperationException();        }

        public String toString() {            return sw.toString();        }    }

    /**     * Default constructor.     */    public MemcachedFilter() {    }

    /**     * @see Filter#destroy()     */    public void destroy() {    }

    /**     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)     */    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {        MemcachedHttpServletResponseWrapper wrapper = new MemcachedHttpServletResponseWrapper((HttpServletResponse) response);        chain.doFilter(request, wrapper);

        HttpServletRequest inRequest = (HttpServletRequest) request;        HttpServletResponse inResponse = (HttpServletResponse) response;

        String content = wrapper.toString();

        PrintWriter out = inResponse.getWriter();        out.print(content);

        if (!inRequest.getMethod().equals("POST")) {            String key = inRequest.getRequestURI();            mmc.set(key, 5, content);        }    }

    /**     * @see Filter#init(FilterConfig)     */    public void init(FilterConfig fConfig) throws ServletException {        try {            mmc = new MemcachedClient(new InetSocketAddress("localhost", 11211));        } catch (IOException e) {            e.printStackTrace();            throw new ServletException(e);        }    }}

First, the dependency: for memcached communication, we used spymemcached client. It is a simple and easy to use memcached library. I won’t explain all the code, line by line, but I can tell the idea behind the code: first, call doFilter method on FilterChain, because we want to get the response and work with that. Take a look at the MemcachedHttpServletResponseWrapper instance, it encapsulates the response and makes easier to play with response content.

We get the content, write it on response writer and put it in cache using the MemcachedClient provided by spymemcached. The request URI is the key and timeout is 5 seconds.

web.xml

Last step is to add the filter on web.xml file of the project, map it before the VRaptor filter is very important for proper working:

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">    <display-name>memcached sample</display-name>

    <filter>        <filter-name>vraptor</filter-name>        <filter-class>br.com.caelum.vraptor.VRaptor</filter-class>    </filter>

    <filter>        <filter-name>memcached</filter-name>        <filter-class>com.franciscosouza.memcached.filter.MemcachedFilter</filter-class>    </filter>

    <filter-mapping>        <filter-name>memcached</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>

    <filter-mapping>        <filter-name>vraptor</filter-name>        <url-pattern>/*</url-pattern>        <dispatcher>FORWARD</dispatcher>        <dispatcher>REQUEST</dispatcher>    </filter-mapping>

</web-app>

That is it! Now you can just run Tomcat on port 8080 and nginx on port 80, and access http://localhost on your browser. Try some it: raise up the cache timeout, navigate on application and turn off Tomcat. You will still be able to navigate on some pages that use GET request method (users list, home and users form).

Check the entire code out on Github: https://github.com/fsouza/starting-with-vraptor-3. If you have any questions, troubles or comments, please let me know! ;)

[Andrews Medina] DSLs em Python

Saturday, December 11th, 2010

introdução

DSL (Domain Specifc Language) é uma linguagem limitada com o objetivo de atender um domínio específico. Ou seja, DSLs são uma forma diferente de programar, onde é criado uma sintaxe que se aproxime mais do domínio do qual ela faz parte.

A linguagem de programação escolhida para construir a DSL afeta totalmente em como será a sintaxe da DSL. Geralmente, linguagens menos burocráticas como ruby são mais utilizadas para construção de DSLs.

Python mesmo sendo dinâmica tem várias burocracias, como endentação obrigatória, monkey patch limitado, que limitam a construção de DSLs, mas por outro lado, Python, tem características que podem ser utilizadas, como: sobrecarga de operadores, decorators e modificação do encoding.

Nesse post eu mostrarei como utilizar essas técnicas para construção de DSLs, e mostrar bibliotecas em Python que já as utilizam.

sobrecarga de operadores

Há duas formas de utilizar a sobrecarga de operadores para construir DSLs. Uma delas é mantendo a função original do operador, mas modificando o domínio em que ele atua, e a outra forma é modificando a função do operador, utilizando ele apenas para facilitar a sintaxe.

Para exemplificar como podemos utilizar um operador, mantendo sua função original, mas modificando seu domínio, vamos analizar o funcionamento o operador de adição (+):

Ele pode ser utilizado para realizar a adição, somando dois números:



>>> 2 + 2
4

Pode ser utilizado para concatenar duas strings:



>>> “andrews” + “medina”
“andrews medina”

Seguindo esse raciocínio poderíamos usar o operador de adição para concatenar duas imagens:



>>> imagem1 + imagem2

Um framework que faz um ótimo uso de sobrecarga de operadores, mantendo sua função é o cocos2d. Ele utiliza operadores para concatenar ações/animações:



>> sprite.do( Reverse(scale) + scale )

A outra forma, de usar operadores é apenas sobrescrevendo ele para usar ele de uma forma que fique ‘visualmente’ agradável, criando assim uma DSL.

Um exemplo de biblioteca que utiliza essa técnica é a should_dsl:



>> 1 |should| equal_to(1)

decorators

Usar decorators para descrever características de uma função, é uma técnica para escrever DSLs, tornando o código mais claro e legível.

Um exemplo, seria construir um decorator para tornar funções assíncronas:



@assync
def funcao():
pass

O uso de decorators é bem comum. Outro caso é utilizar decorators para definir o roteamento de ur utilizado por uma função:



@url(‘foo’)
def foo():
pass

O django utiliza decorators para facilitar a construção de filtros e template tags:



@filter
def hello():
return “hello”

Além do django, o lettuce, web2py, flask utilizam decorators.

modificação do encoding

Uma outra forma mais livre de construir DSLs em Python é utilizando o encoding para modificar a sintaxe do Python.

Essa técnica não é muito comum e eu particularmente não gosto dela, por ela modificar a sintaxe original da linguagem.

Um exemplo de uso dela pode ser visto num projeto criado pelo Fernando Meyer, chamado YETI (https://github.com/fmeyer/yeti):



describe Bowling:
def before_each:
self._bowling = Bowling()

it “should score 0 for gutter game”:
self._bowling.hit(0)
self._bowling.score |should_be.equal_to| 0

Para quem quiser entender mais como funciona o YETI, Meyer escreveu um post sobre isso: http://planeta-globo.com/2009/09/05/writing-a-domain-specific-language-dsl-with-python/

conclusão

Para saber quando usar sobrecarga de operadores, decorators ou criar uma sintaxe diferente na hora de criar uma DSL, lembre-se sempre de torná-la mais simples possível e sempre condizente ao domínio.

[Igor Sobreira] Extending the User model in Django

Saturday, December 11th, 2010

Django brings a built-in user authentication system, it includes an User model which has the most common attributes. But in most applications you may need to store additional attributes to users. Django has a way to do this too.

Extending using foreign key

Basically you create your UserProfile model with a OneToOneField to User:

class UserProfile(models.Model):
    user = models.OneToOneField('auth.User')
    bio = models.TextField()
    # ...

and define in on settings.py

AUTH_PROFILE_MODULE = 'accounts.UserProfile'     # app name (dot) model name

From now on your User objects will have a get_profile() method.

I personally can’t see a reason to use this setting (and I hate “getters” methods), you just need to do this:

class UserProfile(models.Model):
    user = models.OneToOneField('auth.User', related_name='profile')
    bio = models.TextField()
    # ...

See the related_name='profile' parameter, now you don’t need the get_profile() method anymore, just use user_instance.profile.

But there is a small problem here, if the user instance don’t have a profile related to it you will receive an ObjectDoesNotExist exception. This happens with get_profile() too. And it’s not good to handle the exception every time you access the profile. The simplest way to solve this is connect to django.db.models.signals.post_save on the User model and create your UserProfile instance related to it

from django.db.models import signals
from accounts.models import UserProfile

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)

signals.post_save.connect(create_user_profile, sender=User)

Why subclassing User is a bad idea

There are a few reasons I prefer to create user profiles as another model instead of just subclassing the default User. If you think for a while, an user has a lot to do in your site, and there are at a few default steps:

  • first she needs to register, confirm by email, and so on
  • login and logout, change and reset password
  • admins may need to manage groups and permissions, to restrict user actions, offer features to specific groups
  • manage profile, with personal information

Django doesn’t handle the first topic, there is a great app to handle registration.

The second and third topics can be done with django.contrib.auth app, this is exactly it’s purpose.

And then you have the forth topic, which is profiles. As you can see, it can be done as a separate app. A user has a profile. So makes sense to have a profile attribute in the User object.

If you split features in apps like this it’s easier to reuse too, that’s the idea of django apps after all! The django-registration is an example. And as you can imagine, there are apps to manage profiles too.

Editing User profile in admin

If you’re using admin you may want to edit the UserProfile fields in the same page as the User fields, and it’s possible using admin inlines. Here is how you admin configuration will look like:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
from django.contrib.auth.models import User

from accounts.models import UserProfile

class UserProfileInline(admin.TabularInline):
    model = UserProfile

class UserAdmin(DjangoUserAdmin):
    inlines = (UserProfileInline,)

admin.site.unregister(User)
admin.site.register(User, UserAdmin)

Conclusion

As you can see, it quite easy to manage user profiles in django. Although there is a way to hook you profile model in settings.py, you can do it with a simple foreign key. And as usual, there are a few reusable apps around to handle the generic stuff.

[Emerson Macedo] Os desafios do Novo Player de Vídeos da Globo.com

Tuesday, December 7th, 2010

Faz aproximadamente 4 meses que mudei para a equipe de Webmedia da globo.com. Nessa ida, eu esperava alguns desafios um pouco diferentes, o que acabou acontecendo logo no começo.

Novo Player Globo.com

Indo direto ao ponto, meu primeiro projeto importante foi desenvolver junto com meu time um novo player de vídeos para a globo.com, o qual chamamos de Player 2.0. Pra mim isso era algo totalmente novo, pois meu contato com desenvolvimento Flash/ActionScript havia sido muito pouco, num projeto no início de 2009. Como a maioria já sabe, o desenvolvimento de um Player de Vídeos hoje em dia precisa necessariamente ser feito em flash, pois é o runtime que tem o maior alcance de usuários. A parte de vídeos do html5 ainda tem diversas lacunas a serem preenchidas e é necessário ainda um bom tempo para que a “massa” de usuários tenham seus browsers atualizados com suporte a essa tecnologia.

Nesse desenvolvimento do Player, pude perceber juntamente com meu time que desenvolver na plataforma do Flash já é o um grande desafio, pois a plataforma e o runtime tem alguns detalhes que você precisa entender e saber lidar, caso contrário você vai ter muita dor de cabeça.

Runtime e Sistema Operacional

Quando você desenvolve alguma coisa em Flash, especialmente um Player de Vídeos, um ponto onde é preciso tomar bastante cuidade é com o Runtime do Flash (vulgo Flash Player). O Runtime pode ter comportamentos diferentes em diferentes versões do próprio runtime e também do sistema operacional. Por algumas vezes nós passamos por situações onde percebemos que o Player não estava funcionando em uma versão específica do Runtime no Internet Explorer 6 no Windows XP. Isso causou uma certa correria, mas felizmente conseguimos resolver o problema antes de colocar no ar e não houve impacto.

Lições aprendidas e tivemos tomar algumas medidas, entre elas testar em Linux, Windows e Mac e nos principais browsers e Runtimes do Flash como parte do nosso Definition of Done (DoD). Na prática, hoje uma estória não é dada como pronta se não tivermos certeza que o que foi feito funciona nos diversos environments pré estabelecidos. No início isso era parte do DoD do Sprint, mas após passarmos por uma situação, onde achamos um problema no IE6 (pra variar) bem no último dia do sprint, e que iria colocar todo esse Sprint por água abaixo, movemos esse item do DoD do Sprint para o DoD das estórias. Acabamos resolvendo o problema sem impactar no sprint, mas o desfecho poderia ter sido outro.

Testes Automatizados

Nos tempos atuais, é quase unânime a importância de testes automatizados no desenvolvimento de software. Todo programador deveria saber os princípios de testes automatizados e aplicá-los no seu dia a dia. Infelizmente, existem alguns environments que não facilitam muito esse tipo de prática. Nesses casos, é necessário lidar com o problema de maneira pragmática, caso contrário as coisas não andam. Diferentemente de outras tecnologias, neste caso não podemos escolher alguma opção diferente, pois a opção é uma só (o Flash).

No desenvolvimento do Player, nós usamos o FlexUnit como ferramenta principal de testes automatizados. Dentro do que ele se propõe, faz seu trabalho bem feito, e facilita bastante os testes. Tem suporte a testes assíncronos, e sua documentação explica bem as principais funcionalidades.

Uma coisa que tem nos atrapalhado bastante são os frameworks de test doubles. Nenhum dos frameworks que testamos funcionou no nosso ambiente. Aqui, algo que percebemos no densenvolvimento para Flash foi que cada tutorial na internet pode funcionar numa minor/revision version do runtime e na outra aquele tutorial já não funciona. É bem complicado e custei a aceitar, mas é assim que funciona nesse environment. Ainda não descarto a possibilidade de que poderiamos insistir mais pra conseguir alguma coisa melhor, ou que não soubemos fazer direito, mas não poderiamos ficar empacados nisso, sem mover nosso projeto pra frente.

Mesmo com essas dificuldades, estamos conseguindo fazer uma quantidade boa de testes e isso tem nos ajudado muito.

Continous Integration Server

Outro desafio bem complicado que tivemos foi ter um build server funcionando bem e rodando nossos testes automatizados. Mais uma vez os tutoriais da internet acabam não funcioando direito. Pra piorar, pra você rodar testes ActionScript 3, que é a linguagem do Flash, é necessário levantar uma instância do FlashPlayer, que precisa de um Servidor X. Essa instância vezes não fecha, fica travada, ou apresenta alguns problemas que nada tem a ver com os testes da aplicação. Custamos a perceber isso, mas foi o que aconteceu.

No fim das contas, hoje temos nosso servidor de build e integração contínua funcionando bem, e com poucos problemas.

Estratégia de Migração

Fazer uma mudança no Player de Vídeos da globo.com não é uma tarefa simples. Não poderíamos simplesmente colocar um Player novo no lugar do antigo e ver o que aconteceria. Além de ser um baita risco seria uma baita irresponsabilidade. Precisavamos então pensar numa estratégia …

Antes  do momento de colocar o primeiro release no ar, decidimos usar um catálogo de vídeos com acesso bem pequeno. Para isso, criamos uma opção que ativa/desativa a versão nova em cada catálogo, individualmente. Dessa forma, poderiamos voltar para a versão antiga IMEDIATAMENTE, em caso de algum problema.

Essa estratégia foi perfeita, pois conseguimos pegar diversos pontos de melhoria, e fazer os ajustes necesários sem gerar impacto para os usuários. Com os ajustes feitos e uma nova versão no ar, resolvemos então colocar em mais um catálogo de vídeos, dessa vez um com mais acessos. Nesse momento nosso player ainda não suportava vídeos ao vivo, portanto ainda não podiamos colocar em catálogos como o do Globo News, pois caso contrário teriamos problemas. Isso provou como a nossa escolha de criar uma opcão de ir habilitando sob demanda se mostrou bastante acertada, pois assim que terminamos a funcionalidade de vídeos ao vivo, habilitamos essa nova versão do Player para o Globo News.

Hoje, estamos já com quase todos os catálogos de vídeos usando esse Novo Player. Em breve, todos os vídeos da Globo.com serão servidos por ele. Isso só não aconteceu ainda porque temos algumas estórias com alguns detalhes que tornam viável a substituição completa do Player que está no ar hoje. O mais interessante de tudo é que estamos tendo impacto e stress zero, graças e estratégia bem traçada por todo nosso time.

Conclusão

Esse começo na equipe de Webmedia está sendo ótimo. Criar um Player de Vídeos do zero tem sido uma experiência fantástica, apesar de todas as dificuldades.

Algumas das coisas mais importantes que estou tirando de lição desse projeto é que (1) nem sempre dá pra fazer tudo certinho com todos os testes automatizados, etc, etc etc, (2) as vezes estamos num vendor lock-in onde não dá pra sair e ai você tem que saber superar com os problemas do enviroment dessa tecnologia e (3) migrar uma aplicação que afeta quase todos os sites de uma empresa do tamanho da globo.com sem causar impacto em ninguém é difícil, mas não impossível.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

[Tiago Peczenyj] Oportunidades globo.com

Monday, December 6th, 2010

Olá amigo desenvolvedor

Nós estamos com as seguintes vagas abertas aqui na area de Videos da globo.com:

http://gist.github.com/594208
http://gist.github.com/594210
http://gist.github.com/594214

Você vai notar que as vagas são bem parecidas, mas existem algumas diferenças bem fortes de uma para outra. A primeira é para o time que desenvolve “a cara” dos nossos produtos, o que o publico final vê. A segunda é o time que lida com sistemas que o publico final não vê, mas que são a base para o que o ele vê no final das contas. E a terceira é nosso time mais próximo de sysadmin-dev, por isso conhecimentos de redes e sistemas operacionais são um requisito (inclusive este é o meu time).

No caso, você seria entrevistado para a vaga que sentir mais identificação, mas não tem problema se você se interessar por outra no decorrer do processo. Para todas, como você deve ter percebido, nos preocupamos não apenas com o perfil técnico, mas também em saber como as pessoas são, o que querem e se suportam tomar um chopp conosco. :-)

Vale lembrar que as contratações são para regime CLT para trabalhar de forma presencial no Rio de Janeiro-RJ, na Barra da Tijuca. Contatos podem ser feitos por intermédio do email contido na descrição das vagas.

[Tiago Peczenyj] Oportunidades globo.com

Monday, December 6th, 2010

Olá amigo desenvolvedor

Nós estamos com as seguintes vagas abertas aqui na area de Videos da globo.com:

http://gist.github.com/594208
http://gist.github.com/594210
http://gist.github.com/594214

Você vai notar que as vagas são bem parecidas, mas existem algumas diferenças bem fortes de uma para outra. A primeira é para o time que desenvolve “a cara” dos nossos produtos, o que o publico final vê. A segunda é o time que lida com sistemas que o publico final não vê, mas que são a base para o que o ele vê no final das contas. E a terceira é nosso time mais próximo de sysadmin-dev, por isso conhecimentos de redes e sistemas operacionais são um requisito (inclusive este é o meu time).

No caso, você seria entrevistado para a vaga que sentir mais identificação, mas não tem problema se você se interessar por outra no decorrer do processo. Para todas, como você deve ter percebido, nos preocupamos não apenas com o perfil técnico, mas também em saber como as pessoas são, o que querem e se suportam tomar um chopp conosco. :-)

Vale lembrar que as contratações são para regime CLT para trabalhar de forma presencial no Rio de Janeiro-RJ, na Barra da Tijuca. Contatos podem ser feitos por intermédio do email contido na descrição das vagas.

[Rafael Biriba] OI Velox invade a privacidade de seus usuários com campanha de seu navegador

Thursday, December 2nd, 2010

Desde o dia 30 de novembro, muitos usuários do OI Velox vem reclamando de terem recebido um spam com a campanha publicitária do novo navegador (Imagem abaixo)

http://navegador.oi.com.br/
http://navegador.oi.com.br/

Não há nada de errado com o navegador disponibilizado pela empresa, a não ser, pela forma inusitada de como foi divulgada.

Infelizmente passei pela experiência na madrugada do dia 02/dez/2010, onde eu estava navegando no site do submarino, e do nada, a minha requisição foi interceptada pela oi velox, e no lugar do produto que escolhi, apareceu a publicidade do navegador oi. (Tela abaixo)

Agora, eu fico me perguntando… E se eu estivesse efetuando uma compra no site ? Essa campanha publicitária poderia atrapalhar e muito no processo.

Ou melhor, uma prova online, daqueles tipos que tem uma mensagem “Verifique sua conexão de internet, para que não haja interrupção durante o teste”. Esses tipos de provas são aplicadas por empresas de RH por exemplo.

Continuei olhando a página do navegador, e fiquei surpreso quando li o conteúdo dessa página…

Para quem não consegue ler da imagem, vou transcrever abaixo:
O serviço NÃO ESTÁ ATIVO para esta conta de usuário neste computador. Se desejar desativar também para todas as contas de usuário e todos os computadores em sua CASA, clique no botão “Desativar para a sua CASA”.

Não satisfeitos em interceptar a conexão no meu computador, ele ainda me diz que vai fazer isso com todos os computadores da casa. Não teve jeito, corri no meu outro computador (um desktop velhinho), e comecei a navegar até que finalmente a mensagem apareceu, e como sempre, indevidamente.

Investigando o problema mais a fundo, descobri que o site da OI cria cookies locais para identificar os usuários que optaram ou não pelo uso do navegador. Sabe o que isso significa ? Que se você limpar seus cookies, logo a mensagem do navegador da oi aparecerá para você novamente !!!

Não acredita que ele faz essas verificações com cookies ? É tudo tão ridículo, que está escrito na política de privacidade, no item cookies (http://navegador.oi.com.br/status/politica_de_privacidade.html)

Tenho certeza que existem leis que proibem esse tipo de atitude. Quando eu assinei o Oi Velox, assinei um provedor de internet e não lembro de ter aceitado nada referente a campanhas publicitárias, principalmente as que invadem a sua tela, interrompendo a minha experiência de navegação…

Agora, o que esse tal navegador faz ? Monitora você… Todos os links que você clicar, todas as buscas que fizer, ele armazena tudo… Com simples propósta de armazenar para te sugerir links de acordo com o seu perfil.

Mas na verdade esse rastreamento é de interesse da OI e seus parceiros, que permite a segmentação do público por publicidade fornecida. Assim fica mais fácil de mostrar anúncios de esporte para que navega muito nas páginas de esporte…

O pior dessa história toda, é que esse rastreamento não é explicado com clareza para os usuários. Não sabemos ao certo, o que pode ser feito com todos esses dados coletados e muito menos a que nível de segurança eles estão guardados.

Isso para mim é uma trapaça, onde é fornecido um serviço( como uma máscara) que promete facilitar a navegação, mas em troca, todo o seus histórico de acesso e navegação ficam a disposição da Oi…

O Serviço é tão ruim, que eu habilitei só para testar e também para poder escrever essa matéria, e depois não consegui achar nenhum link para desativar, ou quepudesse me informar se o serviço estava ativo ou não.

Depois de tanto procurar, achei o link abaixo e parece que consegui desativar. Mas infelizmente, não há nenhum link que possa me garantir que esse serviço não está ativo.

Conclusão: Recomendo que NÃO habilitem esse serviço !! Visite o link: http://navegador.oi.com.br/status/desativado.html e escolha a opção: Desativar para sua a casa. Na dúvida, exclua os seus cookies de navegação para garantir que ainda está no sigilo de sua navegação.

Curiosidade para reforçar a matéria… Você usuário velox, experimente digitar algum link errado… Ao invés de receber a tradicional página não encontrada, aparece uma página da oi, com muitos banners publicitários relacionado ao link que você digitou errado ! Sensacional não ? Até na página de erro existe uma exploração comercial…


Deixo essa matéria em aberto para quem quiser compartilhar a sua opnião…

Google Bookmarks Twitter Yahoo Messenger Orkut Hotmail Google Gmail Delicious Share

Leia também:


[Rafael Biriba] OI Velox invade a privacidade de seus usuários com campanha de seu navegador

Thursday, December 2nd, 2010

Desde o dia 30 de novembro, muitos usuários do OI Velox vem reclamando de terem recebido um spam com a campanha publicitária do novo navegador (Imagem abaixo)

http://navegador.oi.com.br/
http://navegador.oi.com.br/

Não há nada de errado com o navegador disponibilizado pela empresa, a não ser, pela forma inusitada de como foi divulgada.

Infelizmente passei pela experiência na madrugada do dia 02/dez/2010, onde eu estava navegando no site do submarino, e do nada, a minha requisição foi interceptada pela oi velox, e no lugar do produto que escolhi, apareceu a publicidade do navegador oi. (Tela abaixo)

Agora, eu fico me perguntando… E se eu estivesse efetuando uma compra no site ? Essa campanha publicitária poderia atrapalhar e muito no processo.

Ou melhor, uma prova online, daqueles tipos que tem uma mensagem “Verifique sua conexão de internet, para que não haja interrupção durante o teste”. Esses tipos de provas são aplicadas por empresas de RH por exemplo.

Continuei olhando a página do navegador, e fiquei surpreso quando li o conteúdo dessa página…

Para quem não consegue ler da imagem, vou transcrever abaixo:
O serviço NÃO ESTÁ ATIVO para esta conta de usuário neste computador. Se desejar desativar também para todas as contas de usuário e todos os computadores em sua CASA, clique no botão “Desativar para a sua CASA”.

Não satisfeitos em interceptar a conexão no meu computador, ele ainda me diz que vai fazer isso com todos os computadores da casa. Não teve jeito, corri no meu outro computador (um desktop velhinho), e comecei a navegar até que finalmente a mensagem apareceu, e como sempre, indevidamente.

Investigando o problema mais a fundo, descobri que o site da OI cria cookies locais para identificar os usuários que optaram ou não pelo uso do navegador. Sabe o que isso significa ? Que se você limpar seus cookies, logo a mensagem do navegador da oi aparecerá para você novamente !!!

Não acredita que ele faz essas verificações com cookies ? É tudo tão ridículo, que está escrito na política de privacidade, no item cookies (http://navegador.oi.com.br/status/politica_de_privacidade.html)

Tenho certeza que existem leis que proibem esse tipo de atitude. Quando eu assinei o Oi Velox, assinei um provedor de internet e não lembro de ter aceitado nada referente a campanhas publicitárias, principalmente as que invadem a sua tela, interrompendo a minha experiência de navegação…

Agora, o que esse tal navegador faz ? Monitora você… Todos os links que você clicar, todas as buscas que fizer, ele armazena tudo… Com simples propósta de armazenar para te sugerir links de acordo com o seu perfil.

Mas na verdade esse rastreamento é de interesse da OI e seus parceiros, que permite a segmentação do público por publicidade fornecida. Assim fica mais fácil de mostrar anúncios de esporte para que navega muito nas páginas de esporte…

O pior dessa história toda, é que esse rastreamento não é explicado com clareza para os usuários. Não sabemos ao certo, o que pode ser feito com todos esses dados coletados e muito menos a que nível de segurança eles estão guardados.

Isso para mim é uma trapaça, onde é fornecido um serviço( como uma máscara) que promete facilitar a navegação, mas em troca, todo o seus histórico de acesso e navegação ficam a disposição da Oi…

O Serviço é tão ruim, que eu habilitei só para testar e também para poder escrever essa matéria, e depois não consegui achar nenhum link para desativar, ou quepudesse me informar se o serviço estava ativo ou não.

Depois de tanto procurar, achei o link abaixo e parece que consegui desativar. Mas infelizmente, não há nenhum link que possa me garantir que esse serviço não está ativo.

Conclusão: Recomendo que NÃO habilitem esse serviço !! Visite o link: http://navegador.oi.com.br/status/desativado.html e escolha a opção: Desativar para sua a casa. Na dúvida, exclua os seus cookies de navegação para garantir que ainda está no sigilo de sua navegação.

Curiosidade para reforçar a matéria… Você usuário velox, experimente digitar algum link errado… Ao invés de receber a tradicional página não encontrada, aparece uma página da oi, com muitos banners publicitários relacionado ao link que você digitou errado ! Sensacional não ? Até na página de erro existe uma exploração comercial…


Deixo essa matéria em aberto para quem quiser compartilhar a sua opnião…

Google Bookmarks Twitter Yahoo Messenger Orkut Hotmail Google Gmail Delicious Share

Leia também: