Protheus e AdvPL ASP – Parte 04

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:

WEB HeadInfo

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"

ipconfig 1

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:

IMG_3661

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

5 respostas em “Protheus e AdvPL ASP – Parte 04

  1. Pingback: Protheus e AdvPL ASP – Parte 05 | Tudo em AdvPL

  2. Pingback: CRUD em AdvPL ASP – Parte 02 | Tudo em AdvPL

  3. 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?

    Curtir

Deixe um comentário