Simple Web Server (Unicode)

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Simple Web Server (Unicode)

Message par falsam »

Simple Web Serveur est un simple serveur de page HTML statics .

Préalable.
- Purebasic 5.43 (Unicode) Minimum
- HTML et CSS Minimum

Structure du code.
- Lancement du serveur de pages HTML et affichage des connections. ( Procedure Start() )
- Préparation de l'entête HTTP ( Procedure BuildRequestHeader() )
- Traitements des pages demandées par le client* et nvoie des données au client* ( Procedure ProcessRequest() )

* Client = Navigateur

■ Démo http://109.13.115.206:6834/index.html (Open)

Code.

Code : Tout sélectionner

EnableExplicit

Global Title.s = "Simple Server"

Global Port = 6835

Global WWWDirectory.s = "www1/"
Global WWWIndex.s = "index.html"
Global WWWError.s = "error.html"

Global BufferSize = 1024, *Buffer = AllocateMemory(BufferSize), Buffer.s

Global ClientID

Declare Start()                                                 
Declare ProcessRequest()                                         
Declare BuildRequestHeader(*FileContent, FileExtension.s, FileLength)
Declare ClearLog()
Declare Resize()
Declare Exit()                                                  

Start()

;Affichage / Show application
Procedure Start()
  Protected ServerEvent, Result
  
  If Not InitNetwork() 
    MessageRequester(Title, "Can't initialize the network !", 0)
  Else     
    
    ;Création du serveur / Create server 
    If CreateNetworkServer(0, Port)      
      OpenWindow(0, 0, 0, 800, 600, Title, #PB_Window_SystemMenu | #PB_Window_SizeGadget)
      WindowBounds(0, 200, 100, #PB_Ignore, #PB_Ignore) 
      
      EditorGadget(0, 0, 0, 800, 560, #PB_Editor_ReadOnly)
      AddGadgetItem(0, -1, FormatDate("%hh:%mm", Date()) + " | Server listening on port " + Port)
      
      CheckBoxGadget(1, 10, 570, 200, 22, "Show Log") 
      SetGadgetState(1, #PB_Checkbox_Checked)
      
      ButtonGadget(2, 700, 570, 80, 22, "Clear Log")
      
      ;Déclencheur / Trigger
      BindGadgetEvent(2, @ClearLog())
      BindEvent(#PB_Event_SizeWindow, @Resize())
      BindEvent(#PB_Event_CloseWindow, @Exit())
      
      Repeat    
        Repeat : Until WindowEvent() = 0
        
        ServerEvent = NetworkServerEvent()
        If ServerEvent
          ClientID = EventClient()
          Buffer = ""
          Select ServerEvent              
            Case #PB_NetworkEvent_Data 
              Repeat
                FreeMemory(*Buffer)
                *Buffer = AllocateMemory(BufferSize)
                Result = ReceiveNetworkData(ClientID, *Buffer, BufferSize)
                Buffer + PeekS(*Buffer, -1, #PB_UTF8)
              Until Result <> BufferSize
              
              ProcessRequest()
          EndSelect
        Else
          Delay(10)  ; Ne pas saturer le CPU / Don't stole the whole CPU !
        EndIf
      ForEver     
    Else
      MessageRequester(Title, "Error: can't create the server (port " + port + " in use ?)")
    EndIf
  EndIf
EndProcedure

;Demande de traitement / Process Request
Procedure ProcessRequest()
  Protected RequestedFile.s, FileLength
  Protected *FileContent, *Buffer
  
  If Left(Buffer, 3) = "GET"    
    ;Extract page html from "GET /yourpage.html HTTP/1.1"
    RequestedFile = Trim(Mid(StringField(Buffer, 1, "HTTP"), 6))    
    
    If RequestedFile = ""
      RequestedFile = WWWIndex      
    EndIf
    
    ;Mise à jour du log / UPdated log
    If GetGadgetState(1) = #PB_Checkbox_Checked
      AddGadgetItem(0, -1, FormatDate("%hh:%mm", Date()) + " | Client IP " + IPString(GetClientIP(ClientID)) + " load " + RequestedFile) 
    EndIf   
    
    ;Lecture fichier demandé / Read Requested file
    If ReadFile(0, WWWDirectory + RequestedFile, #PB_UTF8)
    ElseIf ReadFile(0, WWWDirectory + WWWError, #PB_UTF8)
    Else
      MessageRequester(Title, "Error: WWW init error")
    EndIf
    FileLength = Lof(0)
                
    ;Initialisation Header HTTP / Init Header HTTP
    *FileContent  = AllocateMemory(FileLength + 200)
    *Buffer = BuildRequestHeader(*FileContent, GetExtensionPart(RequestedFile), FileLength)
    
    ;Ajout contenu fichier / Add file content
    ReadData(0, *Buffer, FileLength)
    CloseFile(0)
    
    ;Envoyer la page HTML au client / Send the HTML page to the client
    SendNetworkData(ClientID, *FileContent, *Buffer - *FileContent + FileLength)
    FreeMemory(*FileContent)
  EndIf  
EndProcedure

;Creation entete HTTP / Create HTTP header
Procedure BuildRequestHeader(*FileBuffer, FileExtension.s, FileLength)
  Protected Week.s = "Sun, Mon,Tue,Wed,Thu,Fri,Sat"
  Protected MonthsOfYear.s = "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec" 
  
  Protected DayOfWeek.s = StringField("Sun, Mon,Tue,Wed,Thu,Fri,Sat", DayOfWeek(Date()) + 1, ",")
  Protected Day = Day(Date())
  Protected Month.s = StringField("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", Month(Date()), ",")
  Protected Year.s = Str(Year(Date()))
  Protected Time.s = FormatDate("%hh:%ii:%ss GMT", Date())
  Protected ContentType.s
  Protected Length
  
  ;Definition du content-type / Setup content-type
  ;Ref : https://fr.wikipedia.org/wiki/Type_MIME
  Select LCase(FileExtension)
    Case "html", "" : ContentType = "text/html"
    Case "css"      : ContentType = "text/css"
    Case "js"       : ContentType = "application/javascript" 
    Case "gif"      : ContentType = "image/gif"
    Case "jpg"      : ContentType = "image/jpeg"
    Case "png"      : ContentType = "image/png"
    Case "txt"      : ContentType = "text/plain"
    Case "zip"      : ContentType = "application/zip"
    Case "pdf"      : ContentType = "application/pdf"
    Default         : ContentType = "application/octet-stream" 
  EndSelect  
  
  ;Création entete / Create header
  Length = PokeS(*FileBuffer, "HTTP/1.1 200 OK" + #CRLF$, -1, #PB_UTF8)                                                             : *FileBuffer + Length
  Length = PokeS(*FileBuffer, "Date: " + DayOfWeek + ", " + Day + " " + Month + " " + Year + " " + Time  + #CRLF$, -1, #PB_UTF8)    : *FileBuffer + Length
  Length = PokeS(*FileBuffer, "Server: "+ Title + #CRLF$, -1, #PB_UTF8)                                                             : *FileBuffer + Length
  Length = PokeS(*FileBuffer, "Content-Length: " + Str(FileLength) + #CRLF$, -1, #PB_UTF8)                                          : *FileBuffer + Length
  Length = PokeS(*FileBuffer, "Content-Type: " + ContentType + #CRLF$ + #CRLF$, -1, #PB_UTF8)                                       : *FileBuffer + Length 
  
  ProcedureReturn *FileBuffer
EndProcedure


Procedure ClearLog()
  ClearGadgetItems(0)  
EndProcedure

Procedure Resize()
  Protected Width = WindowWidth(0)
  Protected Height = WindowHeight(0)
  
  ResizeGadget(0, #PB_Ignore, #PB_Ignore, Width, Height-40)
  ResizeGadget(1, #PB_Ignore, Height - 30, #PB_Ignore, #PB_Ignore)
  ResizeGadget(2, Width - 100, Height - 30, #PB_Ignore, #PB_Ignore)
  
EndProcedure

;Sortie  / Exit 
Procedure Exit()
  CloseNetworkServer(0)  
  End
EndProcedure
Que faire ensuite ?
- Enregistrer le code dans un dossier
- Créer un dossier www
- Coder la page index.html
- Coder la page error.html
- Lancer le serveur
- Coder d'autres pages.
- Laisser des commentaire ^^.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Simple Web Server

Message par Kwai chang caine »

Tiens !!! j'ai ça comme page 8O J'ai utilisé ta page de ATOMIC convertie en UNICODE
Server listening on port 6834
Client IP 127.0.0.1 load index.html
Client IP 127.0.0.1 load favicon.ico
Client IP 163.95.19.52 load index.html
Client IP 163.95.19.52 load favicon.ico
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Simple Web Server

Message par falsam »

Je crois avoir répondu dans le sujet atomic qu'il fallait créer les pages en UTF8 seul

Je vais quand même tester ces pages.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Simple Web Server

Message par Kwai chang caine »

Oui tu as raison, je suis allé relire, j'avais codé en UNICODE et ça avait marché pour ATOMIC :oops:
Pas besoin, je suis passé en UTF8 et ça marche nickel, merci FALSAM 8)

Juste un petit bémol ..j'ai une balise </HTML> qui traine 8O
Atomic Web Server (Unicode)

Ceci est la prémiere page de votre site web. / This is the first page of your website.
</html
Une question me trotte....crois tu que ça serait compliqué de rajouter PHP ?
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Simple Web Server

Message par djes »

Kwai chang caine a écrit :Une question me trotte....crois tu que ça serait compliqué de rajouter PHP ?
8O :mrgreen:
Y'a que KCC pour sortir un truc pareil, avec une telle ingénuité !
Bon courage falsam ! :lol:
Avatar de l’utilisateur
GallyHC
Messages : 1708
Inscription : lun. 17/déc./2007 12:44

Re: Simple Web Server

Message par GallyHC »

Bonjour,

Une toute petite modification au niveau de :

Code : Tout sélectionner

  ;Definition du content-type / Setup content-type
  ;Ref : https://fr.wikipedia.org/wiki/Type_MIME
  Select GetExtensionPart(RequestedFileExtension)
    Case ".css" : ContentType = "text/css"
    Case ".js"  : ContentType = "application/javascript" 
    Case ".gif" : ContentType = "image/gif"
    Case ".jpg" : ContentType = "image/jpeg"
    Case ".png" : ContentType = "image/png"
    Case ".txt" : ContentType = "text/plain"
    Case ".zip" : ContentType = "application/zip"
    Case ".pdf" : ContentType = "application/pdf"
      
    Default     
      ContentType = "text/html" 
  EndSelect
Perso je mettrais :

Code : Tout sélectionner

Default     
      ContentType = "application/octet-stream" 
  EndSelect
Car tu n'est pas sur que ce soit un fichier Texte. Ton lien donne pour cela :
application/octet-stream : flux de données arbitraire. Considéré comme le format « par défaut » dans plusieurs OS, souvent utilisé pour identifier des fichiers exécutables, ou de type inconnu, ou des fichiers qui doivent être téléchargés grâce à des protocoles qui ne fournissent pas de champ « content disposition » dans leur en-tête. La RFC 2046 [archive] le décrit comme un recours pour les sous-types et les types non reconnus.
Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Simple Web Server

Message par falsam »

@Gally: Oui tu as raison. Code modifié.
Djes a écrit :Y'a que KCC pour sortir un truc pareil, avec une telle ingénuité !
+1

@KCC: Et non. Pas de PHP. L'objectif de ce code est d'afficher des pages uniquement statics. Par contre tu peux utiliser JavaScript au dans tes pages HTML

Si tu souhaites gérer la dynamique des pages, alors il faut utiliser la version ++ de Simple Web Server.

:arrow: http://www.purebasic.fr/french/viewtopi ... =6&t=16490
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Simple Web Server

Message par Kwai chang caine »

Merci de ton explication Falsam
J'ai encore du mal à comprendre la différence entre les deux
C'est peut être justement que l'un est statique et l'autre non :oops:
djes a écrit :
Kwai chang caine a écrit :Une question me trotte....crois tu que ça serait compliqué de rajouter PHP ?
8O :mrgreen:
Y'a que KCC pour sortir un truc pareil, avec une telle ingénuité !
Bon courage falsam ! :lol:
Quel "mouqueur" ce DJES :lol:

Bon alors j'ai encore pas tout compris, ou je me suis mal exprimé. ..ou les deux :mrgreen:
Je pensais à faire comme APACHE, car c'est bien de lui qu'on veut se passer ??
Récupérer la page et lorsque l'on détecte du php avec les balises <? Php> et bien on l'envoi a l'exe PHP pour qu'il fasse le job.

Car évidemment ça serait un boulot de guedin de tout recréér les centaines de fonctions PHP, et réinventer la roue.
En plus ce serait ridicule car on ne pourrait pas changer la syntaxe sous peine de se couper du reste du monde..
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Simple Web Server

Message par djes »

Kwai chang caine a écrit :
djes a écrit :
Kwai chang caine a écrit :Une question me trotte....crois tu que ça serait compliqué de rajouter PHP ?
8O :mrgreen:
Y'a que KCC pour sortir un truc pareil, avec une telle ingénuité !
Bon courage falsam ! :lol:
Quel "mouqueur" ce DJES :lol:

Bon alors j'ai encore pas tout compris, ou je me suis mal exprimé. ..ou les deux :mrgreen:
Je pensais à faire comme APACHE, car c'est bien de lui qu'on veut se passer ??
Récupérer la page et lorsque l'on détecte du php avec les balises <? Php> et bien on l'envoi a l'exe PHP pour qu'il fasse le job.

Car évidemment ça serait un boulot de guedin de tout recréér les centaines de fonctions PHP, et réinventer la roue.
En plus ce serait ridicule car on ne pourrait pas changer la syntaxe sous peine de se couper du reste du monde..
Bien sûr que c'est faisable, mais justement, falsam met en place des balises pour faire comme php mais en PB, ce n'est pas pour implémenter un truc qui existe déjà, surtout que c'est hyper lourdingue ! Et vu que c'est de l'Open source, rien n'empêche quiconque de le faire, il donne tous les outils pour.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Simple Web Server

Message par Kwai chang caine »

Aaaaah ok !!!
J'ai cru que j'étais à côté de la plaque :oops:
Perso je suis pas fan de php, mais mettre en place nos propres balise ça va pas rendre les pages de Falsam illisibles par les serveurs "normaux"...
C'est là que je comprends pas tout :oops:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Simple Web Server

Message par falsam »

mettre en place nos propres balise ça va pas rendre les pages de Falsam illisibles par les serveurs "normaux"...
Que tu es Beta ^^ héhé

Les pages comportant ces balises sont uniquement interprétées par le serveur codé avec PureBasic.

:!: Rappel : Ce code ne fait qu'affiché des page statics ne comportant pas ce type de balise :wink:
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Simple Web Server

Message par falsam »

Kwai chang caine a écrit :Juste un petit bémol ..j'ai une balise </HTML> qui traine
Et bien pas chez moi avec le meme test.

Tu peux cliquer sur cette exemple http://109.13.115.206:6834/index.html qui ne sera plus visible à minuit.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Simple Web Server

Message par Ar-S »

Si tu regarde ton code source (de la page web), ta balise de fin n'est pas fermée.

Code : Tout sélectionner

</html
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Simple Web Server

Message par falsam »

Alors là ..... pas de réponse !!!

Si je débogue la variable HTMLContent juste avant l'instruction SendNetworkString() la page HTML est complète avec la balise <html> fermée.

Le rendu de la page est correcte mais pas le code source final. C'est perturbant.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Simple Web Server

Message par falsam »

Rhoo je viens de voir une grosse lacune dans ce code !!!!!

/me cherche une pelle pour s'enfoncer le plus possible dans le sol :oops:
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Répondre