Jump to content

Archived

This topic is now archived and is closed to further replies.

Bruno Augusto

Http...

Recommended Posts

Eu sei bem o que é Request e apenas sei o que é Response.

 

Mas ao manipular o HTTP num nível básico, e trabalhar com classes para isso, quem será minha Request e quem será minha Response

 

A Request receberá a requisição feita, mas o que mais é competência dessa classe?

 

E quem instancia a Response? Quais são as competências dela?

 

Com "competências", me refiro, que tipos de dados elas devem/precisam receber e quais tipos de informações devem fornecer.

Share this post


Link to post
Share on other sites

Basicamente, a Request deve conter os parâmetros passados pelo cliente, então ela teria que conter os dados enviados via Post, Get, Cookies além de outros parâmetros que são devolvidos pelo Router (não sei se está utilizando um, estes parâmetros além de outras coisas, contém o Module/Controller/Action da url requisitada). A classe Response poderia até conter uma forma de pegar/manipular os dados da global $_SERVER, para saber por exemplo, qual o navegador do cliente, etc.

 

Quem instancia a Response é o Controller principal da tua aplicação. A classe Response deve conter, basicamente, os seguintes dados: os headers, o conteúdo (Body) e o código HTTP da resposta (500, 404, 301, 200, etc), além de poder ter metódos para agilizar redirecionamentos.

 

Pelo o que eu estudei é isso, mas se alguém com mais conhecimento quiser criticar de forma construtiva, é bem vindo. ^_^

Share this post


Link to post
Share on other sites

Beleza, vamos à alguns pontos:

 

  • Quem instancia a Response?
     
    Andei vendo que seria aquilo que precisa gerar algum tipo de output. No meu caso acredito que seria apenas a View, mais especificamente, no método render(), certo?
     
  • E a Request apenas lê os cabeçalhos ou os envia também? Ou é uma faca de dois gumes: Ambas as classes manipulam os cabeçalhos, mas apenas a Request envia e apenas a Response os lê (ou o contrário).
     
  • Sobre a manipulação de $_SERVER. Andei vendo a Request do Zend Framework e, por exemplo, ela é quem fornece acesso à esse superglobal bem como, por exempo, obtenção do IP do usuário. E aí? Essa seria mesmo responsabilidade da Response como você disse?
     
  • E quanto às informações da requisição depois de feita, como por exemplo o código de status.
     
    Depois que meu Roteador detectou um Controller que pode gerenciar dada Requisição, eu abro um conexão (cURL ou via Streams) sobre a URL montada desta dita requisição só para pegar essa informações e informar à Response?

Share this post


Link to post
Share on other sites
Quem instancia a Response?

Ao meu ver, o melhor é instanciar a mesma no momento que se instancia a Request, porque? Pelo fato de que toda Requisição exige uma Resposta, mesmo se esta resposta estiver vazia, ou seja, a view não tem nada para renderizar, mas mesmo assim o cliente precisa receber uma resposta do status da requisição, um caso que se aplica como exemplo são Requisições RESTful, onde a resposta esperada para um metódo DELETE não deve conter conteúdo, apenas o código de status 204.

 

E a Request apenas lê os cabeçalhos ou os envia também? Ou é uma faca de dois gumes: Ambas as classes manipulam os cabeçalhos, mas apenas a Request envia e apenas a Response os lê (ou o contrário).

 

Aqui você se enrolou um pouco :P

A Request lê os cabeçalhos da requisição, aqueles enviados pelo cliente, ou seja, ele não deve ter nenhum metódo para gravar cabeçalhos, apenas para ler. Já a Response deve ter metódos para gravar, ler e enviar os cabeçalhos da resposta.

 

Sobre a manipulação de $_SERVER. Andei vendo a Request do Zend Framework e, por exemplo, ela é quem fornece acesso à esse superglobal bem como, por exempo, obtenção do IP do usuário. E aí? Essa seria mesmo responsabilidade da Response como você disse?

Aqui quem se enrolou foi eu. :lol:

Eu coloquei Response onde era para colocar Request.

O correto é a classe de Request manipular estes dados.

 

E quanto às informações da requisição depois de feita, como por exemplo o código de status.

Depois que meu Roteador detectou um Controller que pode gerenciar dada Requisição, eu abro um conexão (cURL ou via Streams) sobre a URL montada desta dita requisição só para pegar essa informações e informar à Response?

Não entendi este ponto, você está criando uma outra URL a partir do Module-Controller-Action? Se for isto, ao meu ver o melhor é, a partir dos dados obtidos, procurar pela classe de Controller que corresponda à requisição, e chamar a action requisitada dentro do mesmo.

Share this post


Link to post
Share on other sites
Quem instancia a Response?

Ao meu ver, o melhor é instanciar a mesma no momento que se instancia a Request, porque? Pelo fato de que toda Requisição exige uma Resposta, mesmo se esta resposta estiver vazia, ou seja, a view não tem nada para renderizar, mas mesmo assim o cliente precisa receber uma resposta do status da requisição, um caso que se aplica como exemplo são Requisições RESTful, onde a resposta esperada para um metódo DELETE não deve conter conteúdo, apenas o código de status 204.

Então cada Controller tem uma Request e uma Response próprias.

 

Mas eu andei lendo que é Request é uma coisa meio única. Tanto que vi até algumas implementações com Singleton.

 

E então?

 

E a Request apenas lê os cabeçalhos ou os envia também? Ou é uma faca de dois gumes: Ambas as classes manipulam os cabeçalhos, mas apenas a Request envia e apenas a Response os lê (ou o contrário).

 

Aqui você se enrolou um pouco :P

A Request lê os cabeçalhos da requisição, aqueles enviados pelo cliente, ou seja, ele não deve ter nenhum metódo para gravar cabeçalhos, apenas para ler. Já a Response deve ter metódos para gravar, ler e enviar os cabeçalhos da resposta.

Com "enviados pelo cliente", você está se referindo a quê? Os Controllers através de algo que o usuário faz na View?

 

Você teria um esquema ou pseudo-código para ilustrar o caso? Não quero duplicar funcionalidades em ambas as classes...

 

Sobre a manipulação de $_SERVER. Andei vendo a Request do Zend Framework e, por exemplo, ela é quem fornece acesso à esse superglobal bem como, por exempo, obtenção do IP do usuário. E aí? Essa seria mesmo responsabilidade da Response como você disse?

Aqui quem se enrolou foi eu. :lol:

Eu coloquei Response onde era para colocar Request.

O correto é a classe de Request manipular estes dados.

Ufa! :P Ainda bem. Já tava me batendo pra entender o porquê de só esse super-array ser isolado em outro canto. :lol:

 

E quanto às informações da requisição depois de feita, como por exemplo o código de status.

Depois que meu Roteador detectou um Controller que pode gerenciar dada Requisição, eu abro um conexão (cURL ou via Streams) sobre a URL montada desta dita requisição só para pegar essa informações e informar à Response?

Não entendi este ponto, você está criando uma outra URL a partir do Module-Controller-Action? Se for isto, ao meu ver o melhor é, a partir dos dados obtidos, procurar pela classe de Controller que corresponda à requisição, e chamar a action requisitada dentro do mesmo.

Olha só. Todas o gatilho desse tópico foi por causa da HttpRequest e da HttpResponse, ambas provenientes de extensão PECL.

 

Veja que na HttpRequest temos aquilo que mais vemos nas Request's de vários frameworks e até de sistemas isolados junto com algumas coisas mais, como por exemplo manipulação de cabeçalhos.

 

E daí que surgiu a dúvida de quem deveria manipulá-los.

 

Agora veja a HttpResponse. Ela tem vários getters e setters... estáticos? Cujas informações não vê simplesmente por instanciar a classe do Controller.

 

Pesquisei sobre, e vi que algumas das informações a serem passadas para ela, poderiam ser obtidas com get_headers().

 

Mas devo mesmo, após detectado o Controller, abrir uma Requisição para esta URL, através dessa função ou de Streams (que pelo visto também dá), para poder pegar as informações e passá-las à Response?

Share this post


Link to post
Share on other sites

Então cada Controller tem uma Request e uma Response próprias.

 

Mas eu andei lendo que é Request é uma coisa meio única. Tanto que vi até algumas implementações com Singleton.

 

E então?

 

Na realidade, a classe de Request e a de Response não devem ter relações diretas com o Controller que vai processar a requisição atual. Elas devem apenas conter os dados referentes à requisição, e a resposta, respectivamente. Elas são classes únicas em cada requisição, por isso muitos implementam como Singleton, mas eu não recomendaria utilizar singleton, pois dificultaria realizar testes.

 

Com "enviados pelo cliente", você está se referindo a quê? Os Controllers através de algo que o usuário faz na View?

 

Você teria um esquema ou pseudo-código para ilustrar o caso? Não quero duplicar funcionalidades em ambas as classes...

 

Em todo processo HTTP existe a troca de cabeçalhos, estes podem ser enviados pelo servidor, ou pelo cliente. Por exemplo, no momento que eu requisito a página do Google, o Firefox envia os seguintes cabeçalhos para o servidor do Google:

GET / HTTP/1.1
Host: www.google.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: x-user-defined,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Cookie: -- removido --
Cache-Control: max-age=0

 

E quando o servidor do Google recebe a minha requisição, e a processa, ele me retorna uma resposta com os seguintes cabeçalhos, junto com o conteúdo da mesma:

HTTP/1.1 200 OK
Date: Fri, 16 Sep 2011 22:57:54 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=UTF-8
Content-Encoding: gzip
Server: gws
Content-Length: 16286
X-XSS-Protection: 1; mode=block

 

A sua classe Request deve ter metódos apenas para ler os cabeçalhos enviados pelo cliente, já a tua classe Response deve ter metódos para manipular os cabeçalhos que serão enviados como resposta para o cliente.

Por exemplo, a sua classe de Request pode ter um metódo getHeaders(), já a tua classe Response, pode/deve ter os metódos addHeader(name, value), getHeaders(), clearHeaders().

 

 

E daí que surgiu a dúvida de quem deveria manipulá-los.

 

Classe Request manipula os headers enviados pelo cliente, classe Response manipula os headers, que serão, enviados para o cliente.

Request -> A requisição do cliente.

Response -> A resposta para o cliente.

 

Agora veja a HttpResponse. Ela tem vários getters e setters... estáticos? Cujas informações não vê simplesmente por instanciar a classe do Controller.

Eu não setaria estes metódos estáticos, eu não sei como funciona estas classes, visto que o código das mesmas deve ser implementado em C, mas provavelmente, no momento que você seta um header, ele automaticamente envia os mesmos. A classe Response além de modificar os headers, ela é que deve enviar a resposta para o cliente, atravês de um metódo do tipo sendResponse(), o qual internamente chama sendHeaders()

 

Mas devo mesmo, após detectado o Controller, abrir uma Requisição para esta URL, através dessa função ou de Streams (que pelo visto também dá), para poder pegar as informações e passá-las à Response?

 

Não, isto aqui deve clarear um pouco o caminho que você deve prosseguir, é o workflow da ZF:

zf-flow-diagram1.png

Share this post


Link to post
Share on other sites

Bom, não vou quotar tudo isso ^_^

 

Agora me confundiu um pouco.

 

Se quem deve instanciar a Request e a Response é Controller, como que eles não vão ter relações diretas?

 

E quanto aos outros tipos de cabeçalho de respostas? A exemplo àqueles que podem ser resgatados nessa HttpResponse da PECL mas não estão presentes no CODE de exemplo? Sei lá, suponhamos que eu precise do ETag, e daí?

 

Via .htaccess eu seto como None, para que, se eu entendi quando ensinado, o browser se encarregue dessa informação. Se eu faço isso, outros sites podem fazer também e, teoricamente esse valor não aparecerá na lista de cabeçahos retornados.

 

Por isso ainda estou "batendo nessa tecla" de abrir uma requisição com o URL detectado no Roteamento.

Share this post


Link to post
Share on other sites
Se quem deve instanciar a Request e a Response é Controller, como que eles não vão ter relações diretas?

Na realidade existem dois Controllers envolvidos na requisição. Um deles é o Front Controller, que é uma classe especial, singleton, que é instanciada durante o bootstrap, é ela a classe principal da aplicação e a que se encarrega de instanciar a classe de Response e Request, além de manipular o flow da aplicação. O outro Controller é o controller normal, aquele que o teu roteador definiu para a requisição atual.

 

E quanto aos outros tipos de cabeçalho de respostas? A exemplo àqueles que podem ser resgatados nessa HttpResponse da PECL mas não estão presentes no CODE de exemplo? Sei lá, suponhamos que eu precise do ETag, e daí?

 

Bastaria criar um metódo para recuperar um único header dentre todos os outros, algo como getHeader( string name ), este metódo iria buscar pelo header especificado na array de headers definidos, caso o mesmo fosse encontrado, ele seria retornado. Se ele não aparece, ele não foi definido. Lembrando que os headers referentes ao ETag que são enviados pelo cliente são: If-Match e If-None-Match (Que correspondem, respectivamente, aos indexes HTTP_IF_MATCH e HTTP_IF_NONE_MATCH na Super Global $_SERVER). Você pode pegar o conteúdo raw da requisição do usuário através do stream php://input.

 

E se planeja usar ETag, recomendo a leitura: http://developer.yahoo.com/performance/rules.html#etags ;)

Share this post


Link to post
Share on other sites

Hmmmm... Agora estamos chegando a algum lugar.

 

No meu caso não tenho esse FrontController mas tenho uma camada extra chamada Application.

 

Cada Application deve conter no mínimo um Controller e uma View Engine, mas pode definir, opcionalmente, um ou mais adaptadores de Banco de Dados ou de Cache.

 

Um Controller instanciado utiliza informações da Request através de um accessor apontando para Application.

 

Sobre o exemplo do E-Tag, não, não vou usar isso (pelo menos não agora), mas seria mesmo correto utilizar APENAS os cabeçalhos que o servidor retornar?

 

Digo, se de repente alguma informação está sendo retornada, mas $_SERVER não a encontra, seria prudente usar outros meios (talvez com a função citada) para ter o que retornar caso falhe? Ou é desnecessário?

Share this post


Link to post
Share on other sites

Sobre o exemplo do E-Tag, não, não vou usar isso (pelo menos não agora), mas seria mesmo correto utilizar APENAS os cabeçalhos que o servidor retornar?

 

Sim, se o cliente precisar de um conteúdo que possui uma ETag definida, ele vai enviar os headers que eu informei no post anterior, caso os headers não estejam presentes, o cliente deseja um novo conteúdo.

 

Digo, se de repente alguma informação está sendo retornada, mas $_SERVER não a encontra, seria prudente usar outros meios (talvez com a função citada) para ter o que retornar caso falhe? Ou é desnecessário?

 

Se você achar que o $_SERVER não está retornando o header, basta buscar os headers manualmente através do stream php://input, ou qualquer outro metódo/função que tenha acesso ao conteúdo completo que o cliente enviou.

Share this post


Link to post
Share on other sites

Surgiram algumas perguntas com relação à requisição feita e resposta recebida.

 

Acidentalmente, encontrei esse Knowledge Base onde em sua seção HTTP Headers ele classifica 53 tipos de cabeçalho em três categorias: Geral, Request e Response.

 

Com isso:

 

  • Essa classificação existe realmente ou foi algo que oautor do tópico decidiu criar para elucidar alguma coisa (não mencionada)?
     
  • Se essa classificação existe significa que os cabeçalhos do tipo Response não devem em hipótese alguma ser enviados pelo sistema, "na ida"?
     
    Assim como os cabeçalhos do tipo Request devem ser ignorados durante a leitura da Response recebida?
     
  • Ness site constam muitos outros cabeçalhos que não estão pressntes na RFC 2616, Seção 14. E daí? Devo também considerá-los ou me ater fielmente à RFC?

Share this post


Link to post
Share on other sites

Essa classificação existe realmente ou foi algo que oautor do tópico decidiu criar para elucidar alguma coisa (não mencionada)?

 

O autor apenas pegou os cabeçalhos declarados na especificação e os separou de acordo com o tipo de metódo no qual eles podem ser utilizados.

 

Se essa classificação existe significa que os cabeçalhos do tipo Response não devem em hipótese alguma ser enviados pelo sistema, "na ida"?

 

Assim como os cabeçalhos do tipo Request devem ser ignorados durante a leitura da Response recebida?

 

"na ida" você diz do cliente para o servidor? Se sim, na realidade, não é que não podem, eles apenas serão ignorados, sendo assim os mesmos não devem ser enviados. Não há necessidade de você enviar, por exemplo, um cabeçalho do tipo User-Agent na Resposta enviada do servidor à requisição do cliente, o mesmo se aplica ao header ETag, que só deve ser enviada na resposta do servidor, pois é ele que deve gerar a ETag.

 

Ness site constam muitos outros cabeçalhos que não estão pressntes na RFC 2616, Seção 14. E daí? Devo também considerá-los ou me ater fielmente à RFC?

 

O ideal é você seguir a especificação.

Share this post


Link to post
Share on other sites

O autor apenas pegou os cabeçalhos declarados na especificação e os separou de acordo com o tipo de metódo no qual eles podem ser utilizados.

Posso assumir que é uma classificação correta, então? Ou tem alguém no lugar errado?

 

"na ida" você diz do cliente para o servidor? Se sim, na realidade, não é que não podem, eles apenas serão ignorados, sendo assim os mesmos não devem ser enviados. Não há necessidade de você enviar, por exemplo, um cabeçalho do tipo User-Agent na Resposta enviada do servidor à requisição do cliente, o mesmo se aplica ao header ETag, que só deve ser enviada na resposta do servidor, pois é ele que deve gerar a ETag.

Beleza, se não deve, não vai. :thumbsup:

 

O ideal é você seguir a especificação.

Aqui subdivido em outra pergunta.

 

A exemplo do header X-Powered-By. É largamente usado por diversas aplicações, mas não é reconhecido como parte da RFC 2616.

 

E aí? Existe um meio termo?

Share this post


Link to post
Share on other sites

Posso assumir que é uma classificação correta, então? Ou tem alguém no lugar errado?

 

Eles estão corretos, pode se basear neles se desejar.

 

 

A exemplo do header X-Powered-By. É largamente usado por diversas aplicações, mas não é reconhecido como parte da RFC 2616.

 

E aí? Existe um meio termo?

 

O meio termo aqui é usar o bom senso, você pode sim utilizar outros headers que não foram declarados pela especificação, mas não deve confiar totalmente nos dados passados nos mesmos, eles devem ser usados meramente para informação complementar. Existem tantos outros headers que não estão na especificação, alguns muito úteis, como os headers do Wildfire usados pelo FirePHP.

Share this post


Link to post
Share on other sites

Hmmmm....

 

E você saberia me dizer pelo menos que critérios usar numa busca para chegar numa lista com esses "candidatos a white heads"?

 

De cabeça mesmo só cinhecia um, e agora dois ^_^

Share this post


Link to post
Share on other sites

Ahhhh! Não acredito. Virei o assunto de ponta cabeça e nada :angry: <_< :lol:

 

Mais duas coisas (tu já deve estar gritando aí dooutro lado).

 

- No RestPatterns.org, tem outros além desses seis. De onde vieram? Deveria eu considerá-los também?

 

- Nenhum desses da Wikipedia estão presentes lá, logo não estão categorizados. Como que eu saberia se são Response ou Request Headers?

Share this post


Link to post
Share on other sites

Mais duas coisas (tu já deve estar gritando aí dooutro lado).

 

Ahuahua, esquenta com isso não. B)

 

No RestPatterns.org, tem outros além desses seis. De onde vieram? Deveria eu considerá-los também?

 

Sim, como eu havia falado, existm vários outros, a Wikipedia cita apenas os mais usados, podem existir outros, você pode criar outros, etc.

 

Nenhum desses da Wikipedia estão presentes lá, logo não estão categorizados. Como que eu saberia se são Response ou Request Headers?

 

#Common non-standard request headers

#Common non-standard response headers

Share this post


Link to post
Share on other sites

Mais um 'causo'

 

Criei verificadores para todos o 41 ou 47 (não tenho como ver agora) cabeçalhos mas usei a RFC 2616.

 

Daí na página da Wikipedia sobre o os cabeçalhos não-padrão, são mencionados dois links em particular, um nas referências e outro nos links externos.

 

Pois bem.

 

O segundo link, referente à RFC 4229 tem uma lista monstruosa de cabeçalhos. Tem todos (acredito eu, que não comparei aidna) os da RFC 2616 e mais um monte.

 

O primeiro link lista todos os Cabeçalhos permanentes. Mas apenas dois supostamente regulamentados pela RFC 2616. A maioria é pela RFC 4229 e alguns mais por outras tantas RFC's diferentes.

 

E agora? Qual é a VERDADEIRA RFC que regulamenta os cabeçalhos?

 

Esse negócio tá complicando demais pro meu gosto. Podia ter numa página só "esse são os cabeçalhos, vá e use-os com sabedoria", mas nããããããooo..... :P

 

Prefiro usar .. http://br.php.net/manual/en/book.http.php, é da PECL mas eu tenho as dll's para php nts vc9 e vc6. e php ts.

Pois é, mas estou querendo compreender a fundo o funcionamento e não simplesmente utilizar.

Share this post


Link to post
Share on other sites

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.