25 de nov. de 2009

Erro com o Cache-Control no Internet Explorer

Estava buscando justificativas para um erro que ocorria com o sistema de meu cliente, e o erro era muito diferente, do que eu havia visto até hoje.

Contexto


Tínhamos dois ambientes e os dois ambientes, um na intranet e outro na internet, possuíam a mesma versão de código fonte e bibliotecas, tudo absolutamente normal, porém em determinada página que o usuário acessava para fazer download na internet não funcionava, estava dando erro, dizia que não encontrava a página. Mas existia uma outra variável, esta página retorna um relatório, ela gera um array de bytes e envia para o cliente como arquivo para download, em inúmeros formatos como excel, html, pdf, entre outros, mas mesmo assim marcava como página não encontrada, e então iniciei minha análise. Eis que muito tempo analisando o ambiente na qual o aplicativo se estabelecia e o código fonte que gerava estes arquivos me deparei com alguns headers de definição de Cache na página, mas mesmo assim não me atentei a este detalhe, foi então que comecei a isolar a situação em um projeto demonstrativo e então consegui encontrar o erro em si.
No projeto demonstrativo consegui simular o erro, porém tenho que tentar acessar a página que gera o array de bytes diretamente.

Descrição do problema

O código fonte adicionava os seguintes headers:
     this.Context.Response.ClearContent();
   this.Context.Response.ClearHeaders();
   this.Context.Response.AppendHeader("Cache-Control", "no-cache");
   this.Context.Response.AppendHeader("Cache-Control", "private");
   this.Context.Response.AppendHeader("Cache-Control", "no-store");
   this.Context.Response.AppendHeader("Cache-Control", "must-revalidate");
   this.Context.Response.AppendHeader("Cache-Control", "max-stale=0");
   this.Context.Response.AppendHeader("Cache-Control", "post-check=0");
   this.Context.Response.AppendHeader("Cache-Control", "pre-check=0");
   this.Context.Response.AppendHeader("Pragma", "no-cache");
   this.Context.Response.AppendHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT");

Mas até ai qual o problema de se dizer que uma página não será gravada no cache?

Bom para o Internet Explorer, não gravar no cache é uma coisa tão séria, que ele decide não gravar a página/arquivo em lugar algum (nem em uma pasta temporária), apenas o mantém em memória e renderiza isso na tela. Mas ainda não chegamos ao ponto central do erro, quando o IE decide fazer isso não sabe se a resposta é uma página html ou um excel, etc, ou melhor não verifica se o resultado é uma página, ou outra coisa.


No caso de um arquivo xls (Excel, ou qualquer outro formato), o Internet Explorer faz uma chamada para o método IPersistFile::Load de um ActiveX, mas quando o método tenta carregar, o arquivo não é encontrado, pois o Internet Explorer não gravou nenhuma cópia temporária do arquivo, para que ele possa ser aberto, portanto acontece um erro de arquivo não encontrado.


Mas devo alertar que este erro acontece apenas com o Internet Explorer e realizei o teste apenas com as verões 6 e 7, também realizei o teste com o Google Chrome, Opera e Mozilla Firefox, todos conseguiram baixar o arquivo com sucesso.

Solução

Encontrei uma nota de suporte da microsoft informando que este erro ocorre apenas com protocolos seguros SSL, mas no meu caso não tínhamos isso e mesmo assim o problema ocorreu.
Bom vamos aos fatos, na  nota de suporte da microsoft, é expresso que como solução do problema remover o "no-cache" do "Control-Cache", mas disso nem tudo é verdade. Porque tanto o "no-cache" quanto o "no-story" do "Control-Cache" apresentaram este problema no teste realizado, na nota também é expresso que o "no-cache" do "Pragma" apresenta problemas, mas não foi possível simular este problema no nosso teste, nos deixando assim com a incerteza de que o problema realmente exista com o "Pragma", mas de qualquer maneira a melhor saída para esta situação é :
  1. Caso seja realmente necessário não manter o conteúdo no cache, adicione o "no-cache" apenas do "Pragma", que apresentou uma probabilidade menor de apresentar erros.
  2. Caso perceba que não irá fazer diferença entre adicionar ou não em cache, opte pelo padrão, pois dessa maneira você evita que problemas com o Internet Explorer ocorra, não adicione nada.
Simular o erro no Projeto de exemplo
  1. Faça download do arquivo zip
  2. Descompacte o arquivo em qualquer pasta que desejar.
  3. Abra o Visual Studio 2008 (qualquer versão).
  4. Acesse o item de menu File > Open > WebSite.
  5. Selecione a pasta que foi descompactada com o nome de "AspNet ControlCache Error".
  6. Pressione F5 ou "Run".
  7. Uma página irá abrir com um botão, clique no botão.
  8. Nesta primeira parte o download não ocorrerá pela sequência de eventos, mas substitua a url para a página na url " .../AspNet ControlCache Error/Download.aspx" , e ai sim o problema ocorrerá.
  9. Para solucionar o problema comente as linhas:   
    this.Context.Response.AppendHeader("Cache-Control", "no-cache");
    this.Context.Response.AppendHeader("Cache-Control", "no-store");
  10. Pressione novamente F5 ou "Run" e execute o teste novamente.

Links

Caso os links do post não funcionem aqui segue a lista de links:
Nota de suporte da Microsoft: http://support.microsoft.com/default.aspx?scid=kb;en-us;316431
Projeto de Exemplo: http://www.easy-share.com/1908531596/AspNet ControlCache Error.zip

21 de ago. de 2009

Multiple Upload IE8 (fakepath)

Bom estou escrevendo este artigo para detalhar um novo requisito da ferramenta Internet Explorer 8, mesmo por que eu procurei sobre o assunto, mas não encotrei muitas respostas, então acabei descobrindo um problema.

O IE 8 possui agora um item de segurança também existente no Opera Browser:A substituição do caminho do arquivo por um caminho falso.

Imagine que antes quando você selecionava um arquivo o caminho poderia ser capturado e enviado a um servidor, e via código seria possível acessar quaisquer arquivos existentes na sua máquina, até de maneira oculta, com isso o acesso a arquivo de senha gravadas para auto autenticação em sites e contas de e-mail, etc. Também é possível acessar cockies, entre outras informações. Lógico, quando se sabe o caminho em que estes arquivos estão gravados. Porém quando se tem a estrutura de pastas do sistema operacional(C:\ ou D:\) estes arquivos podem ser acessados, pois os locais de gravação seguem determinado padrão do próprio sistema operacional(e o SO pode ser identificado via javascript).

Mas como posso desenvolver um componente que funcione, sem que o usuário tenha que seguir procedimentos de adicionar o site como seguro, e etc? Tem como fazer isto?

Bom, o problema dos componente de Multi Arquivos da Web, é que eles criam os objetos de inputFile em tempo de execução, porém somente quando os arquivos devem ser realmente enviados. E geralmente a seleção dos arquivos é feita por apenas um componente input, e após isto o CAMINHO é gravado em uma lista, para que quando o arquivo for enviado um novo input seja criado e acessado pelo servidor.

O problema esta quando o componente tenta capturar o caminho do inputFile, agora quando o javascript tenta acessar o atributo "value" do inputFile o mesmo retorna o caminho falso, para que a segurança e integridade dos arquivos e senhas dos usuários seja garantida.


A solução é sempre que um arquivo tiver que ser selecionado, um novo objeto do tipo inputFile deve ser criado, pois com isso não iremos necessitar de nenhuma iteração com o caminho do arquivo, apresentando no máximo o nome do arquivo em uma lista.

Espero que as informações ajudem.

Multiple Upload IE8 (fakepath) (inglês)

(Translation done by Google Tradutor)
Well I am writing this article to detail a new requirement of the tool Internet Explorer 8, I even tried on the subject but not Choose from many responses, then I discovered a problem.

IE 8 now has a safety feature, also present in the Opera Browser: Replacing the file path for a false path.

Imagine that before when you select a file path could be captured and sent to a server, and via code would be able to access any existing files on your machine, even covertly, thus access to the password file written to auto authentication sites and email accounts, email, etc.. You can also access cockies, among other information. Sure, if you know the path where these files are saved. But when you have the folder structure of the operating system (C: \ or D: \), these files can be accessed, because the shooting locations follow certain standard operating system itself (and the OS can be identified via javascript).

But how can I develop a component that works without the User has to follow procedures to add the site as safe, etc? It aims to do this?

Well, the problem of component Multi Web Archive, is that they create inputFile objects at runtime, but only when the files should be actually sent. And usually the selection of files is done by only one component input, and after that the PATH is recorded in a list, so that when the file is sent a new input is created and accessed by the server.

The problem is when the component attempts to capture the path of inputFile, now when the javascript tries to access the attribute "value" of inputFile it returns the false path, so that the security and integrity of files and passwords of users is guaranteed.

The solution is whenever a file is to be selected, a new object of type inputFile should be created, because with this we will not require any interaction with the file path, with a maximum file name in a list.

I hope the information will help.

15 de jun. de 2009

Seu software economiza energia?

Segundo uma pesquisa realizada pela empresa Google Inc., 15.000 buscas significam, em emissão de CO2, a produção de 1 x-burguer.

Isso não é nada ?

Vamos fazer uma conta básica.

Quantas pessoas existem no mundo? Aproximadamente 6,6 bilhões.

Considerando que 1% da população faça pesquisas na internet a cada 1 hora.
6.600.000.000 x 0.01 = 66.000.000 de pessoas fazendo consultas por hora

Um estudo realizado pela "NUA Surveys" sugere que em 2000 existiam mais de 359 milhões de usuários nas maiores potencias econômicas do mundo

66.000.000 X 24 horas por dia = 1.584.000.000 de pessoas por dias.

se cada uma delas fizer 1 consulta teremos 1.584.000.000 de consultas.
1.584.000.000 / 15.000 = 105.600.000 de x-burguers.

Parece muito?
Consideramos apenas 1% da população por hora, imagina se avaliar a quantidade de consultas realizadas por hora que tenho certeza ser mais que 66 milhões, considere que pessoas pesquisam inúmeros assuntos durante seus dias de trabalho e que pela noite milhares de pessoas pesquisam sobre seus interesses.

É... descobrimos que a tecnologia pode ser altamente agressiva ao meio-ambiente.

Mas o que eu como desenvolvedor, arquiteto, analista ou líder de equipe posso fazer? O que eu tenho a ver com isso?

Bom, é um pouco complicado falar sobre este assunto pois precisaríamos de muitas evidências e estudos, mas tentarei aninhá-las aqui.

Black to the world


Quando desenvolvemos aplicativos com fundos escuros temos maior economia na utilização do monitor...
Dúvida?

Pensando exatamente nisso o site blackle foi criado, é uma ilustre iniciativa para um mundo de TI mais verde, limpo e econômico
http://www.blackle.com/ - Este site é uma interface que permite realizar consultas no google com maior economia, possui um contador que demonstra a quantidade de Watts economizados pelo site.
Tabela de Watts por cor
White - 74 Watts
Fuchsia - 69 Watts
Yellow - 69 Watts
Aqua - 68 Watts
Silver - 67 Watts
Blue - 65 Watts
Red - 65 Watts
Lime - 63 Watts
Gray - 62 Watts
Olive - 61 Watts
Purple - 61 Watts
Teal - 61 Watts
Green - 60 Watts
Maroon - 60 Watts
Navy - 60 Watts
Black - 59 Watts

Fonte: http://www.graphicsoptimization.com/diy/displaycolors.htm


Best Pratices

O que as melhores práticas tem a ver com a redução de consumo de energia?

Não encontrei nenhum estudo sobre isso, mas raciocinemos...

Quando eu utilizo singleton por exemplo, estou economizando memória, e por sua vez economizando a energia que seria gasta para alocar um novo objeto na memória.

Com a reutilização de código ganhamos em espaço em disco, em utilização de memória e processamento(Cache do processador).

Que coisa ... será que ainda existem dúvidas de que economizamos uma peque e singela parte do mundo com melhores práticas.

Green Leader

Acredito que onde mais podemos economizar energia é durante o desenvolvimento do software.

Os líderes de projetos de software não se preocupam com a questão ambiental, pois não é evidente que a função de um líder é avaliar o bem da sua equipe (comunidade)?

O bem para as pessoas também inclui se preocupar com a qualidade de vida do lugar onde elas vivem.

Existem inúmeras atitudes que podem fazer com que a equipe economize energia, algumas delas são:
    1. desligar o computador quando o integrante for embora, caso necessário somente desligar o monitor.
    2. reduzir o brilho dos monitores da equipe
    3. reduzir o consumo de copos plásticos, induzir o uso de copos individuais de porcelana ou vidro
    4. reduzir a intensidade da luz do ambiente da equipe
    5. evitar longas jornadas de trabalho
    6. em locais pouco movimentados conduzir as pessoas a apagarem a luz quando não houver ninguém.
    7. reduzir o número de documentos impressos e gravados
    8. reduzir a utilização de ar condicionado
Estas são apenas algumas atitudes.

Conclusão

Cada vez mais as corporações pensam em fazer com que suas atividades sejam cada vez mais alinhadas com os objetivos da sociedade e da sua comunidade, não penas por ser um ambiente favorável ao trabalho, mas também por ser um mundo novo onde clientes e usuários são mais experientes e extremamente mais exigentes, e assim forçados a se preocupar com o meio ambiente e as atividades sociais.
Com estes estudos conseguimos encontrar bases para iniciar a redução dos devidos consumos tanto de energia elétrica quanto de objetos que degradam o meio ambiente de forma letal.
Reconheço que faltam alguns pontos neste post mas tento aqui expor a preocupação das empresas e da sociedade e relacionar a Tecnologia de informação que pode ajudar tanto a diagnosticar problemas com o meio ambiente quando ajudar a recupera-lo.

7 de mai. de 2009

Importância da customização de controles(.NET)

Controles customizados, geralmente, são deixados de lado pelos arquitetos, pois nem sempre é evidente que futuramente, possa haver uma adição funcional no Control Padrão.

Com o avanço das tecnologias e a Orientação a Objetos, vemos a oportunidade de criar controles com certa simplicidade e produtividade.

Mas o que justificaria customizar controles já prontos, como o TextBox, ListBox, DropDownList?

Este é o assunto que irei abordar nesta postagem.

OBS: usarei aqui como base os controles do ".NET" como base, pois não tenho conhecimento a fundo de outras tecnologias.


Justificativas

Os controles do .NET são bastante funcionais e todos eles herdam de uma única classe base(Control).

Vamos usar o TextBox(WebControl) para exemplificar as justificativas.

Supondo que tenha desenvolvido um sistema que da e-commerce, e para isto eu tenha utilizado um controle do tipo TextBox para o que o usuário possa digitar a quantidade de em determinado item do pedido.
Que problemas podem ocorrer com o uso do TextBox do .NET?

Bom, este controle é ótimo, mas não possuí um bloqueio ou máscara para impedir o usuario de digitar um caracter inválido no conteúdo do componente. E que talvez este bloqueio fosse importante para os usuários(Clientes), até para que antes de clicar em comprar isto seja impedido ao invés de validado.

Quando isso for alterado, se não tiver sido criado um controle customizado, teríamos que criar uma função javascript e adicioná-la em cada página, seja com um arquivo js ou uma função adicionada diretamente na página, e ainda teríamos que, em todos os TextBox que necessitam desta validação, adicionar o atributo com a chamada para a função. E tudo isso com muita separação, dificultando a manutenção do código.

Desta maneira você gera mais demanda para a empresa ? Gera mais valor ? Pois é será que a manutenção de aplicativos é rentável? Esta é uma grande pergunta, mas também é assunto para outra postagem.

Mas para seguirmos as melhores práticas adotaremos a resposta de que não seria rentável.

E ai teríamos que criar um time ou uma quantidade de horas absurda para fazer a mesma alteração em lugares diferente, para uma evolução tão simples como mudar um campo de Texto que permita o tratamento de alfanuméricos.

Sendo que a criação de ou apenas a herança de alguns componentes é tão produtivo quanto é recomendável, vale a pena, principalmente, em um projeto de médio a grande porte a Customização de controles.

Abaixo alguns códigos de exemplo:
//Exemplo Simples
public class SimpleCompositeControlDesigner : CompositeControlDesigner
{
public override bool AllowResize
{
get
{
return false; }
}
}

//Exemplo simples de herança
public class SimpleText : TextBox
{
}

6 de mai. de 2009

Aplicações On-line ou Off-line?

Como defensor das ferramentas web, poderia enumerar aqui as vantagens de se utilizar ferramentas tão poderosas quanto a do GMail, Twiter, Meebo entre outros. Pois é, são provas infalíveis de que a Web é altamente poderosa, em inúmeros sentidos e vários quesitos, mas ainda existem problemas a se considerar.


Todos os exemplos que utilizei acima são de aplicativos bastante interessantes que somente disponibilizam serviços que necessitam de acesso a internet para que sua existência faça sentido, em sua maioria são aplicações de comunicação e no inicio era esta a intenção da internet, disseminar conhecimento e estabelecer formas de comunicação mais baratas, pois a internet a anos já alcançou este objetivo, e agora uma nova era vem a tona, a era da "externalização de aplicativos".

Tem coisa pior para o usuário do que ele pegar aquele CD, DVD, BlueRay, HD-DVD, Disquete, Pen Drive, Link de Download, mandar rodar e clicar em Próximo...Próximo e Fim?

De inicio podemos ficar um tanto quanto inconformados com esta condição, mas os clientes e usuários de sistemas não querem mais gastar seus precisos 350 Gigabytes da HD para que o programa/software simplesmente fique instalado e o usuário só vai abrir e usar em 10% do seu tempo. É... é muito difícil aceitar mas o mundo mudou, as pessoas mudaram, e a "'Informática' evoluiu e virou 'Tecnologia de informação'".

Poucas empresas se prestaram a inovar a Web, isso para não dizer que pessoas isoladamente se dedicaram a este tipo de inovação. Mas mesmo com essas pessoas os aplicativos ainda necessitam de muitos ajustes.
Mas e ai, já tem como usar estas aplicações on-line? Elas são realmente seguras?
A resposta para as duas perguntas é positiva, mas eu vou explicar um pouco mais a causa.
As empresas de TI(Tecnologia de Informação), que tem como produtos finais serviços, como e-mail, mensagens, blog, fotolog, sites, entre outros... trabalham com um acordo de nível de serviço que garante que o serviço fornecido fique disponível por exemplo 99% durante o ano, e isso garante que nós usuário teremos o serviço disponível a maior parte das vezes que tentarmos acessa-lo.
Outro recurso existente é o termo de uso do aplicativo, nele possui todos os seus direitos e deveres. E a política de privacidade dos serviços garante que nossas informações sejam guardadas a sete chaves e garantindo a segurança de nossas informações.
Por estes motivos digo que a Web é um local seguro se usado com prudência, assim como um motorista que não usa o cinto de segurança esta correndo um risco, não muito visível, pois o motorista não acredita que ele possa bater o carro, mas o risco existe. Com a web a história é a mesma, como eu posso estar recebendo um e-mail de cobrança de passagens aéreas se eu não comprei nada pela internet, ou eu nunca fui viajar para a Carochinha do Sul, nem abra o link.
Porém as aplicações web do tipo Google Docs, por exemplo, podem ser úteis, mas imagine que você precise editar um arquivo e não esteja na internet, e ai?
Hoje os serviços não disponibilizam nenhum tipo de utilização Off-line, eles até tem sim uma maneira, mas não é muito inteligente, por isso, acho que ainda existem falhas.
Mas as coisas estão evoluindo, as aplicações web estão ficando cada vez mais poderosas, porém acredito que o ideal é unir os dois mundos, até por efeito de backup, é muito interessante nos resguardarmos quando falamos de documentos e informações importantes.
Podemos chegar a conclusão de que as aplicações Web ajudam bastante no dia-a-dia, porém ainda existem alguns problemas nas aplicações, que com o tempo serão melhorados ou corrigidos.

5 de abr. de 2009

Performance de Software

Já tive algumas experiências um pouco atordoantes com relação a performance de Software e conforme estudamos sobre o assunto descobrimos que é muito difícil chegar a performance ideal, principalmente quando temos um "time" trabalhando no mesmo produto(software), mas como fazer com que seu software tenha uma performance aceitável?

Pare e pense quais são as opções, qual o custo-benefício de cada uma delas?

Imagine em seu caso o que será melhor?
Alguns pontos que podem fazer diferença para que seu software tenha performance são:

Otimização utilização de Memória
A utilização da memória pode ser uma questão bastante importante quando se necessita processar grandes massas de dados, pois a cada iteração podemos estar criando áreas na memória sem necessidade.

Criação de objetos, variáveis e iterações(linha de código) sem necessidade são as maiores causas da queda de performance.

Como por exemplo geração de "Log" do processamento, qual o custo benefício de deixar algumas linhas de código que escrevem em um arquivo, event log, banco, etc. será que um simples tratamento de erro não faça a captura das informações necessárias para a solução de um problema.

Utilização de "string", para cada "" ou "texto" referenciado em código é criada uma área na memória para armazenar a informação referenciada, por isso é importante usar o string.Empty ele é uma área única na memória que tem o valor "", com isso nenhuma área desnecessária será criada na memória. Outra questão é a concatenação dos textos, algumas linguagens oferecem opções de concatenação mais eficientes do que um simples (+), como no .NET a classe StringBuilder.

Remover todos os objetos e variáveis alocados em memória que não serão mais utilizados, com linguagens não gerenciadas isto soa como um pré-requisito, mas ainda assim existem muitos programas que deixam a memória alocada. Já com o código gerenciado a maioria dos desenvolvedores não se preocupam com isto, por que a máquina virtual possui uma ferramenta denominada como "Coletor de Lixo", esta ferramenta de em determinado período de tempo, vasculha a área da memória que é de sua responsabilidade e avalia se existem objetos/variáveis que podem ser removidos da memória, o grande problema nisto é que quando temos softwares para tratar muitos dados em sequência este tempo pode não ser suficiente para liberar o espaço na memória e é ai onde podemos obter grandes ganhos na performance, e por este motivo devemos forçar com que este espaço seja removido da memória.

A sequência de carregamento dos dados pode ser importante também, como por exemplo carregar uma árvore de informações, porém somente os primeiros itens da árvore aparecerão e de acordo com as iterações do usuário carrego os itens filhos. Para apoiar este conceito, na Web existe uma técnica de desenvolvimento denominada "AJAX" que é a junção de determinadas tecnologias para que as informações transmitidas sejam menores e carregadas de acordo com a necessidade.

Boas práticas de desenvolvimento(Design Patern)
Algumas boas práticas de desenvolvimento também podem ser utilizadas para ganhar performance.

Infelizmente o assunto é bastante extenso, mas com o tempo vou tentar abordar algumas das boas práticas aqui no blog, mas enquanto isso segue um link
http://pt.wikipedia.org/wiki/Padr%C3%B5es_de_projeto_de_software


Reutilização de código
A reutilização de código não reduz apenas as linhas de código no programa, também reduz o tamanho dos executáveis gerados, fazendo com que seu programa fique mais leve para ser carregado na memoria.


Conclusão
 A performance de software pode ser obtida de várias maneiras, porém o ideal é avaliar os benefícios de cada opção para a sua situação.