Introdução
Nos posts anteriores sobre AdvPL ASP, vimos até o momento três alias virtuais usados para receber parâmetros ( HTTPGET / HTTPPOST ) e controlar variáveis de seção de usuário (HTTPSESSION). Agora, vamos ver mais dois alias virtuais: HTTPHEADIN e HTTPHEADOUT.
Alias Virtual HTTPHEADIN
Cada requisição HTTP possui um formato interno, separada em cabeçalho (ou Header) e corpo (ou Body). Atenção, estamos falando do protocolo HTTP, e não do header e body de um formulário HTML.
Quando um Web Browse ou um cliente de aplicação WEB faz uma requisição via HTTP, esta requisição é acompanhada de algumas tuplas chave/valor, colocadas no cabeçalho da requisição, que indicam por exemplo o tipo da requisição (GET, POST, …), o tipo do conteúdo enviado na requisição (texto, html, imagem, …), a codificação do conteúdo (ANSI, UTF-8 ou outro CodePage), algumas informações sobre o Web Browse ou da aplicação Cliente que está fazendo a solicitação, entre outros identificadores de uso específico.
Usando o Google Chrome, por exemplo, temos uma janela especial chamada DevTools, onde temos ferramentas que permitem investigar por dentro uma requisição feita pelo Web Browse a um determinado servidor, os parâmetros da requisição e seu retorno. Após abrir a janela do DevTools e digitar a URL http://localhost/ , a requisição enviada ao Web Server foi:
GET / HTTP/1.1 Host: localhost Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6 Cookie: SESSIONID=41a79408567715479073622c71988001 If-Modified-Since: Fri, 30 Nov 2018 00:30:20 GMT
Só nesta requisição existe um universo de informações. Não vou entrar nos méritos internos de cada uma, mas apenas nas que realmente importam para o momento, e na forma de recuperá-las.
Da mesma forma que os demais alias virtuais, o alias virtual HTTPHEADIN permite fazer a leitura de um determinado valor a partir do seu nome. Por exemplo:
HTTPHEADIN->CONNECTION deve retornar a string “keep-alive”
HTTPHEADIN->HOST deve retornar a string “localhost”
Agora, o que acontece se eu tentar recuperar o valor de “User-agent” ? HTTPHEADIN->USER-AGENT não é um formato válido para o AdvPL, o compilador vai entender que você quer pegar o valor HTTPHEADIN->USER e fazer uma subtração operação aritmética de subtração da variável “AGENT” , que não existe.
Pensando nesta possibilidade, qualquer caractere que faz parte do nome de uma chave no alias virtual HTTPHEADIN, que não seja válido como nome de variável ou de identificador, será trocado pelo caractere “_” (underline). Desse modo, para recuperar o valor de User-Agent, você deve usar HTTPHEADIN->USER_AGENT
HTTPHEADIN – Valores adicionais
Quando o Web Browse ou a aplicação cliente fez uma requisição HTTP ao Web Server, esta conexão foi aberta sobre o protocolo TCP/IP. Logo, mesmo que a requisição HTTP possa ser minimalista e não ter muitos detalhes, é possível obter dentro do prococolo TCP/IP qual é o IP de Origem da conexão, e qual é a porta TCP usada na conexão aberta pelo Cliente. O IP da Conexão, por exemplo, pode ser recuperado e gravado em um LOG de requisições ou de atividade do Web Site, para uso posterior em estatísticas ou mesmo auditoria de operações. Para obter estes valores, usamos respectivamente:
HTTPEADIN->REMOTE_ADDR HTTPEADIN->REMOTE_PORT
Estes campos retornam respectivamente um valor “C” caractere, contendo o IP Client da Conexão, e um valor “N” numérico contendo a porta dinâmica TCP da máquina Client que fez a requisição.
Seguindo a mesma linha dos posts anteriores, vamos criar um arquivo chamado headinfo.aph, e dentro dele colocar o seguinte conteúdo:
<html><body> <pre> Host ........: <%=HTTPHEADIN->HOST%> Connection...: <%=HTTPHEADIN->CONNECTION%> User-Agent ..: <%=HTTPHEADIN->User_Agent%> Remote Addr..: <%=HTTPHEADIN->REMOTE_ADDR%> Remote Port..: <%=HTTPHEADIN->REMOTE_PORT%> </pre> </body></html>
E, dentro do fonte ASPThreads.prw, inserir mais uma entrada na lista de páginas, para ao receber o link “headinfo.apw”, processar e retornar a função H_HeadInfo() — que corresponde ao arquivo headinfo.aph compilado.
case cAspPage == 'headinfo' cReturn := H_HEADINFO()
E, ao testar esta chamada no meu ambiente, usando http://localhost/headinfo.apw, eu obtive o seguinte resultado na tela do Web Browse:
Agora, vamos ver o que acontece se eu acessar esta página usando um iPhone? Vejamos, primeiro eu preciso achar o IP da minha máquina na rede de casa. Como estou usando Wi-fi, basta eu usar o prompt de comando do Windows (cmd) e usar o comando IPCONFIG, e procurar o endereço IPV4 da interface de rede Wi-fi. Como meu sistema operacional está em Inglês, eu consigo usar alguns comandos adicionais para filtrar os resultados:
ipconfig | findstr /i "Address Adapter"
A interface e o valor que eu quero estão destacados em vermelho. Agora, acessando o Chrome do meu telefone, eu digito a URL
http://192.168.0.4/headinfo.apw
E com ela eu recupero as seguintes informações:
Alias Virtual HTTPHEADOUT
Bem, da mesma forma que uma requisição HTTP é dividida em cabeçalho e corpo, uma resposta de uma requisição também têm esta mesma divisão. Quando você solicita através de um Web Browse ou Cliente HTTP um link de uma página em AdvPL ASP, o próprio Web Server do Protheus monta um cabeçalho de retorno da requisição, com alguns valores pré-definidos. Vou usar a mesma requisição do ultimo teste, e rodar ela com a janela do DevTools aberta. As informações que eu quero estão em uma aba chamada “Response Headers”, que devem mostrar algo assim:
HTTP/1.1 200 OK Date: Fri, 30 Nov 2018 01:34:01 GMT Server: Application Web Server MIME-version: 1.0 Content-type: text/html Last-modified: Fri, 30 Nov 2018 01:34:01 GMT Set-cookie: SESSIONID=68c0be02ceaec73ddfcf14281c4f1909 X-Frame-Options: SAMEORIGIN Content-Length: 284
Este cabeçalho de retorno foi montado pelo Web Server do Protheus, logo que a página AdvPL ASP foi procecssada, e a função ASPConn() retornou a string cHTML. A requisição foi processada com sucesso (código de retorno HTTP 200), a data de processamento, o retorno deve ser tratado pelo Browser como um texto html (definido pelo Content-type), e o tamanho do HTML retornado foi de 284 bytes.
Lembram-se no post anterior, quando eu falei de SESSIONS de usuário? O Web Server do Protheus retorna um Cookie de memória chamado SESSIONID, gerado para esta instância de Browse, para saber nas próximas requisições que se trata da mesma instância e/ou usuário. Pode comparar este valor com o valor recebido demonstrado no exemplo dos Headers da requisição HTTP — os valores estão diferentes, pois entre um teste e outro, eu fechei o Browser e abri novamente. Mais para frente vamos ver um alias virtual que permite lidar com Cookies de memória, então vamos entrar neste assunto novamente e com maior profundidade.
Voltando ao alias virtual HTTPHEADOUT, ele foi criado para que você possa, durante o processamento de uma requisição de AdvPL ASP, criar um novo valor de retorno, para ser acrescentado no Header de retorno da requisição HTTP para o Web Browser ou Cliente que fez a solicitação. PAra ver a lista de campos mais usadas, veja os links de referência no final do post.
Normalmente você não precisa utilizar diretamente o alias HTTPHEADOUT, inclusive por que ele têm a restrição de não permitir a criação de campos de retorno usando por exemplo o símbolo “-“, existem outras funções feitas especificamente para mexer em valores default. O uso projetado para este alias virtual é a possibilidade de criar um header com um nome de identificador exclusivo, para uma integração entre sistemas por exemplo.
Conclusão
Falta pouco para cobrir o básico do AdvPL ASP. Se você começou a ler sobre este assunto agora, pegue os posts desde o primeiro da sequência de AdvPL ASP, o entendimento de boa parte do conteúdo dos posts daqui para a frente requer esta leitura.
Agradeço novamente a audiência, e desejo a todos TERABYTES DE SUCECSSO !!!
Referências
- LISTA DE CAMPOS DE CABEÇALHO HTTP. In: WIKIPÉDIA, a enciclopédia livre. Flórida: Wikimedia Foundation, 2018. Disponível em: <https://pt.wikipedia.org/w/index.php?title=Lista_de_campos_de_cabe%C3%A7alho_HTTP&oldid=53118158>. Acesso em: 12 set. 2018.
Acho louvável o seu esforço, mas já ouviu falar em ecmascript6 e react?
CurtirCurtido por 1 pessoa
Opa, já sim …risos… o objetivo deste esforço é didático. Primeiro fazer no modo “roots”, depois fazer com um Framework, e avaliar as diferenças 😀
Abraços
CurtirCurtir
Pingback: Protheus e AdvPL ASP – Parte 05 | Tudo em AdvPL
Pingback: CRUD em AdvPL ASP – Parte 02 | Tudo em AdvPL
Julio, bom dia.
Obrigado por compartilhar, uma perguntar, saberia dizer se quando conecto usando a função advpl httppost() em um site externo(www), como faria pra manter a sessão dessa conexão ativa?
CurtirCurtir