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