Página 1 de 2

Classe Httpd

Enviado: 22 Jun 2016 08:53
por Vlademiro
Pessoal, descobri recentemente a classe httpd e estou aprendendo através dos exemplos no contrib.

Tenho algumas perguntas :

( 1 ) Alguém do grupo já usa essa classe ? Existe algum tipo de teste de carga desse servidor ? Será que ele aguenta mesmo várias conexões ?

( 2 ) Esse servidor tem alguma relação com o programa shellinabox ?

Classe Httpd

Enviado: 22 Jun 2016 10:30
por Kapiaba

Classe Httpd

Enviado: 23 Jun 2016 15:02
por Kapiaba

Classe Httpd

Enviado: 23 Jun 2016 18:51
por fladimir
Não consegui entender ainda a funcionalidade desta classe? seria auxiliar em projetos WEB?

Tentei compilar o exemplo da pasta contrib pra dar uma olhada da seguinte maneira

Código: Selecionar todos

hbmk2 eshop.prg
deu o seguinte

Código: Selecionar todos

install packge hbssl and input file hbssl.hbc for missing harbour function: __HBEXTERN__HBSSL__()
Porém mesmo adicionando hbssl.hbc a compilação permanece... alguém sabe como resolver?

Classe Httpd

Enviado: 24 Jun 2016 14:13
por Vlademiro
O propósito dessa classe é ser o próprio servidor web + sua aplicação. Tudo junto em um único executável. Ainda não testei até onde ele aguenta.

Para conseguir gerar o executável eu desabilitei o ssl, conforme abaixo :

Código: Selecionar todos


         "PrivateKeyFilename"  => "private.key", ;
         "CertificateFilename" => "certificate.crt", ;
         "SSL"                 => .F., ;


Procure no código fonte do eshop e é só trocar o .T. por .F.

Para testar vá no seu navegador e digite o seu endereço IP:porta

Classe Httpd

Enviado: 24 Jun 2016 14:28
por Vlademiro
Complementando...

A porta padrão é 8002

As pastas do servidor são virtuais e estão configuradas no hash conforme abaixo (veja logo após o SSL, na chave Mount) :

Código: Selecionar todos


   IF ! oServer:Run( { ;
         "FirewallFilter"      => "", ;
         "LogAccess"           => {| m | oLogAccess:Add( m + hb_eol() ) }, ;
         "LogError"            => {| m | oLogError:Add( m + hb_eol() ) }, ;
         "Trace"               => {| ... | QOut( ... ) }, ;
         "Port"                => nPort, ;
         "Idle"                => {| o | iif( hb_FileExists( ".uhttpd.stop" ), ( FErase( ".uhttpd.stop" ), o:Stop() ), NIL ) }, ;
         "PrivateKeyFilename"  => "private.key", ;
         "CertificateFilename" => "certificate.crt", ;
         "SSL"                 => .T., ;
         "Mount"          => { ;                  /*  AQUI VOCÊ CONFIGURA AS PASTAS */
         "/hello"            => {|| UWrite( "Hello!" ) }, ;
         "/info"             => {|| UProcInfo() }, ;
         "/files/*"          => {| x | QOut( hb_DirBase() + "/files/" + X ), UProcFiles( hb_DirBase() + "/files/" + X, .F. ) }, ;
         "/app/login"        => @proc_login(), ;
         "/app/logout"       => @proc_logout(), ;
         "/app/account"      => @proc_account(), ;
         "/app/account/edit" => @proc_account_edit(), ;
         "/app/register"     => @proc_register(), ;
         "/app/main"         => @proc_main(), ;
         "/app/shopping"     => @proc_shopping(), ;
         "/app/cart"         => @proc_cart(), ;
         "/"                 => {|| URedirect( "/app/login" ) } } } )
      oLogError:Close()
      oLogAccess:Close()
      ? "Server error:", oServer:cError
      ErrorLevel( 1 )
      RETURN
   ENDIF

Note que a chave do hash é o local onde você deve apontar o navegador. Por exemplo:

http://seuip:8002/hello irá executar a função correspondente.

Existe também um sistema de templates. Note que a pasta app existe (fica dentro da pasta tpl) e tem vários templates, onde o servidor substiui palavras chaves por parâmetros que você pode criar nas suas funções.

Naquele vídeo postado acima pelo colega Kapiaba, o autor já usou um template criado em bootstrap : http://startbootstrap.com/template-over ... b-admin-2/

Ou seja, você sempre tem que conhecer javascript, html ou css, nem que seja o básico para poder fazer algo legal, se vc tentou usar essas tecnologias há alguns anos e desistiu porque achou chato, sugiro que tente agora de novo pois muita coisa evoluiu. A vantagem é que a parte do servidor fica mais simples (eu acho) pois você não precisa trabalhar com cgi e também não precisa de um servidor web de terceiros (Apache, IIS, etc.). Basta a sua aplicação e pronto. O ponto negativo é que o servidor não se compara em robustes a um apache da vida, mas falta testar até onde ele aguenta. Será que uma aplicação com 50 usuários concorrentes é muito para ele ?

Classe Httpd

Enviado: 24 Jun 2016 14:32
por Vlademiro
...uma coisa que eu demorei um pouco para achar foi o shutdown do servidor do exemplo. Como fazer ele parar ?

É simples. Basta abrir outra janela, ir para a pasta do aplicativo e criar um arquivo chamado .uhttpd.stop que ele vai parar.

Classe Httpd

Enviado: 24 Jun 2016 16:46
por fladimir
Obrigado Vlademiro... assim q der dou uma olhada novamente...

[]´s

Classe Httpd

Enviado: 27 Jun 2016 10:18
por Itamar M. Lins Jr.
O ponto negativo é que o servidor não se compara em robustes a um apache da vida,
É possível rodar o apache com arquivos PRG/HB... substituindo o PHP, quem fez diz que é até mais rápido.

Saudações,
Itamar M. Lins Jr.

Classe Httpd

Enviado: 28 Jun 2016 14:05
por Vlademiro
Itamar, vc sabe onde posso encontrar algo nesse sentido ? Integrar apache com harbour ?

Classe Httpd

Enviado: 10 Ago 2016 20:01
por asimoes
Olá Pessoal,

Alguém já conseguiu fazer funcionar?

O máximo que eu consegui foi

http://127.0.0.1:8002/info
http://127.0.0.1:8002/hello

Com erros:

http://127.0.0.1:8002//files/* dá 404 Not Found
http://127.0.0.1:8002/app/login dá 500 Internal Server Error

Classe Httpd

Enviado: 11 Ago 2016 12:40
por Itamar M. Lins Jr.
Ola!
Usei aqui sem nenhum problema, fiz um aplicativo, acesso via navegadores inclusive Android. Já até postei uns fontes...

Httpd + Harbour + DBFCDX + HTML5. Os arquivos ficam com a extensão ".hrb", Não é tipo PHP que o fonte fica misturado.

Saudações,
Itamar M. Lins Jr.

Classe Httpd

Enviado: 11 Ago 2016 17:50
por fladimir
Parabéns itamar...

Procurei o link com os fontes e não localizei, poderia postar?

[]'s

Classe Httpd

Enviado: 17 Ago 2016 13:19
por Itamar M. Lins Jr.
Ola!
Apenas um pedaço, para dar uma ideia ao pessoal. O resto é muito similar...

Código: Selecionar todos

#include "rddleto.ch"
#include "hbwin.ch"

MEMVAR _SERVER, _REQUEST, _GET, _POST, _COOKIE, _SESSION, _HTTP_REQUEST, _HTTP_RESPONSE

REQUEST DBFNTX, DBFCDX, DBFFPT, DBFDBT, LETO
REQUEST HB_LANG_PT,HB_CODEPAGE_PTISO,HB_CODEPAGE_PT850

FUNCTION HRBMAIN(...)
LOCAL cHtml  := "", aOBS:={}, cOBS := "", nRec, cPATH := "//localhost:2812/"
LOCAL cLogin := cSenha := cCodGarcon :=  cGarcon := "", nC
LOCAL cStr   := cCodGrupo := cGrupo:= "", cSection, cKey, cEOL := hb_eol()
Local hINI   := hb_IniRead("\xxx\sistema.ini")
Local cHost  := cSetor := cPadrao := cCodCliente := cCliente := cEscolha := ""
Local nQtd   := 1, nTotal  := nComissao := 0, cCargo := cCodVendedor := ""

cPDV         := uhttpd_GetField( "cPDV" )
cLogin       := uhttpd_GetField( "cLogin" )
cSenha       := uhttpd_GetField( "cSenha" )
cCargo       := uhttpd_GetField( "cCargo" )
cCodCliente  := uhttpd_GetField( "cCodCliente" )
cCliente     := uhttpd_GetField( "cCliente" )
aCodProduto  := uhttpd_GetField( "aCodProduto" )
cCodProduto  := uhttpd_GetField( "cCodProduto" )
aObs         := uhttpd_GetField( "aObs" )
cCodVendedor := uhttpd_GetField( "cCodVendedor" )
aQtd         := uhttpd_GetField( "aQtd" )
cHost        := uhttpd_GetField( "cHost" )
nReg         := uhttpd_GetField( "nReg" )
cEscolha     := uhttpd_GetField( "cEscolha" )

hb_default( @cPDV  , "" )
hb_default( @cLogin, "" )
hb_default( @cSenha, "" )
hb_default( @cCargo, "" )
hb_default( @cCodCliente, "" )
hb_default( @cCliente, "" )
hb_default( @cCodVendedor, "" )
hb_default( @cHost, "" )
hb_default( @cEscolha, "" )

If cEscolha == "GRUPOS" .OR. cEscolha == "GRAVOU"

   cHtml += '<!DOCTYPE html>' + cEOL
   cHtml += '<html lang="pt-BR">' + cEOL
   cHtml += '<head>' + cEOL
   cHtml += '<title>Sistema xxx Web</title>' + cEOL
   cHtml += '<meta charset="WINDOWS-1252" />' + cEOL
   cHtml += '</head>'+ cEOL

   cHtml += '<form name="fechar" action="/cgi-bin/grupos.hrb" method="post">' + cEOL

   cHtml += '<input type="hidden" name="cCodVendedor" value="' + cCodVendedor + '">' + cEOL
   cHtml += '<input type="hidden" name="cPDV"         value="' + cPDV         + '">' + cEOL
   cHtml += '<input type="hidden" name="cLogin"       value="' + cLogin       + '">' + cEOL
   cHtml += '<input type="hidden" name="cSenha"       value="' + cSenha       + '">' + cEOL
   cHtml += '<input type="hidden" name="cCargo"       value="' + cCargo       + '">' + cEOL
   cHtml += '<input type="hidden" name="cEscolha"     value="' + cEscolha     + '">' + cEOL
   cHtml += '<input type="hidden" name="cHost"        value="' + cHost        + '">' + cEOL
   
   cHtml += '</form> <script>document.fechar.submit(); </script></html>'
   Return cHtml

EndIf

//Quando for apenas um item!!!
If hb_IsArray(aCodProduto)
Else

   If Empty(cCodProduto)
      If Len(aCodProduto) = 1
         cCodProduto := aCodProduto[1]
      Else
         Return html_erro("Informe um produto.")
      EndIf
   EndIf
   
   aCodProduto := {}
   AAdd(aCodProduto,cCodProduto)
//   Return html_erro(cCodProduto + "--" + aCodProduto[1])   
EndIf

//Return html_erro(hb_ValToExp(aCodProduto) + "--" + hb_ValToExp(aQtd)+"--"+hb_ValToExp(aObs))   

If hb_IsArray(aObs)
Else
   cOBS := IIF( ValType(aOBS) <> "C", "",aOBS)
   aObs := {}
   AAdd(aObs,cObs) //
EndIf

If hb_IsArray(aQtd)
Else
   nQtd := aQtd
   IF Empty(nQtd)
      Return html_erro("Informe a Quantidade.")
   EndIf   
   aQtd := {}
   AAdd(aQtd,nQtd) //IIF( ValType(aQtd) == "C", IIF(Val(aQtd)==0,1,Val(aQtd)), 1)
EndIf

//cLogin := cripto(AllTrim(cLogin),.f.)
//cSenha := cripto(AllTrim(cSenha),.f.)

HB_CDPSELECT([PTISO])
hb_langselect([PT])
Set Deleted On

RDDSetDefault("LETO")

If select('eq') > 0
   eq->(DBCloseArea())
EndIf

cIndex := cPATH+"estoque.cdx"
DbUseArea(.t.,'LETO',cPATH+"estoque.dbf","eq",.T.,.F.,'PTISO')
DBSETINDEX( cIndex )
eq->(OrdSetFocus(2)) //cod_mercad
//If eq->(DBSeek(cCodProduto))
//Else
//   Return html_erro("Falha procurando: "+cCodProduto)
//EndIf

If select('pdv') > 0
   pdv->(DBCloseArea())
EndIf

cIndex := cPATH+"pdv"+cPDV+".cdx"
cDbPDV := cPATH+"pdv"+cPDV+".dbf"

If leto_file(cDbPDV)
Else
   dbCreate(cDbPDV,Estrutura_pdv(),"LETO",.T.,"PDV")
   index on cod_mercad tag tag01
   index on areaPrint  tag tag02
   pdv->(DBCloseArea())
EndIf

DbUseArea(.t.,'LETO',cDbPDV,"pdv",.T.,.F.,'PTISO')
If leto_file(cIndex) //não precisa leto_file!
   DBSETINDEX( cIndex )
Else
   index on cod_mercad tag tag01
   index on areaPrint  tag tag02
EndIf

cHora := StrTran(FusoHorario(cPATH),":","")

pdv->(OrdSetFocus(1)) //cod_mercad
For nC := 1 to Len(aCodProduto) //Val(nReg)

   If Empty( Val(aQtd[nC]) )
      //If Empty(cCodProduto)
         Loop
      //Else
      //   nQtd := 1
      //EndIf
   Else
      nQtd := Val(aQtd[nC])
   EndIf

      If eq->(DBSeek(aCodProduto[nC]))
         cProduto  := eq->mercadoria
         cPreco    := eq->avista
         nArea     := eq->areaprint
         cCodForn  := eq->cod_fornec
         cCodGrupo := eq->cod_grupo
      EndIf

      If incluir('pdv')
         If MyRlock('pdv')
            pdv->mesa        := cPDV
            
            pdv->cod_client := IIF(Empty(cCodCliente),"000000",cCodCliente)
            pdv->cliente    := IIF(Empty(cCliente),"CONSUMIDOR DIVERSOS",cCliente)    

            pdv->cod_client  := cCodCliente
            pdv->cliente     := cCliente
            pdv->cod_grupo   := cCodGrupo
            pdv->cod_mercad  := aCodProduto[nC]
            pdv->mercadoria  := alltrim(cProduto)
            pdv->quantidade  := Abs(nQtd)
            pdv->preco_unit  := cPreco
            pdv->cod_vended  := cCodVendedor
            pdv->vendedor    := cLogin
            pdv->data_compr  := Date()
            pdv->hora        := cHora
            pdv->obscozinha  := aOBS[nC]
            pdv->qtdcomanda  := Abs(nQtd)
            pdv->areaprint   := nArea
            pdv->comandado   := 'N'
            pdv->cod_setor   := cSetor
         EndIf
      Else
         eq->(DBCloseArea())
         Return html_erro("Falha incluindo: "+cPDV)
      EndIf

Next

eq->(DBCloseArea())

//cLoginCripto := cLogin //cripto(cLogin,.T.)
//cSenhaCripto := cSenha //cripto(cSenha,.T.)

pdv->(DbCloseArea())

cEscolha := "GRAVOU"

cHtml := PDVProdutosVer(cPATH,cPDV,cCodVendedor,cLogin,cSenha,cCargo,cCodCliente,cCLiente,cHost,cEscolha)
Return cHtml

SET PROCEDURE TO "lib.prg"
Obs. Tem partes que o pulo do gato está na HTML5.
Enfim, fica muito bom com rede Wireless interna, (particular) sem deixar os clientes, acessar.(melhor no restaurante usar 2 redes)

Saudações,
Itamar M. Lins Jr.

Classe Httpd

Enviado: 17 Ago 2016 19:00
por fladimir
Parabéns mais 1 vez e obrigado por compartilhar.