Page 1 of 1

Posted: Thu Oct 03, 2002 6:31 pm
by BackupUser
Restored from previous forum. Originally posted by Joseph.

Hello everybody
I'd like to add to the 'Atomic web server' sample the feature that would allow the users to launch a given application (like 'test.exe') located inside the server BaseDirectory$ folder (see details below).
As a start, I have tried something like the following code section, but i am getting some problems.

Any suggestion/help about this topic (of course also about the 'security issues' related to this feature and their possible solutions) will be greatly appreciated.

Thanks in advance

Code: Select all

Case ".exe"
            ContentType$ = "application/exe"

;RunProgram
;Launch an external program. The 'FileName$' should include its path. If the returned 'Result' is 0, the command can't be launched. 

;Possible value for Flags: 
;0: No flags 
;1: Wait until the launched program quits 
;2: Launch the program in invisible mode 

            fname$=appdir$+BaseDirectory$+RequestedFile$
            ; this one doesn't work
            ;fname$=RequestedFile$
            RunProgram(fname$, "", 1) 


I enclose also the complete atomic web server code, just to help in locating sections of code:

Code: Select all

;
; ------------------------------------------------------------
;
;       Atomic Web Server in PureBasic by AlphaSND
;
;           (c) 2001 - Fantaisie Software
;
; ------------------------------------------------------------
;
; 25/03/2001
;   Added path relative feature. It can be started everywhere
;   Added the window to kill it easely
;
; 19/03/2001
;   Added some new features (clients closed automatically)
;
; 17/03/2001
;   First version.
;

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf

Port = 80
BaseDirectory$ = "www/"
DefaultPage$   = "Index.html"
AtomicTitle$   = "Atomic Web Server v1.0"

Global EOL$

EOL$ = Chr(13)+Chr(10)

*Buffer = AllocateMemory(0, 10000, 0)

If CreateNetworkServer(Port)

  OpenWindow(0, 100, 200, 230, 0, #PB_Window_SystemMenu, "Atomic Web Server (Port "+Str(Port)+")")
  
  Repeat
    
    WEvent.l = WindowEvent()
    SEvent.l = NetworkServerEvent()
  
    If WEvent = #PB_EventCloseWindow
      Quit = 1
    EndIf

    If SEvent
      ClientID.l = NetworkClientID()
  
      Select SEvent
      
        Case 1  ; When a new client has been connected...
          
        Case 4  ; When a client has closed the connection...
  
        Default
          RequestLength.l = ReceiveNetworkData(ClientID, *Buffer, 2000)
          Gosub ProcessRequest
          
      EndSelect

    Else
      Delay(20)  ; Don't stole the whole CPU !
    EndIf
    
  Until Quit = 1 
    
  CloseNetworkServer()
Else
  MessageRequester(AtomicTitle$, "Error: can't create the server (port in use ?).", 0)
EndIf
  
End 



Procedure.l BuildRequestHeader(*Buffer, DataLength.l, ContentType$)

  Length = PokeS(*Buffer, "HTTP/1.1 200 OK"+EOL$)                     : *Buffer+Length
  Length = PokeS(*Buffer, "Date: Wed, 07 Aug 1996 11:15:43 GMT"+EOL$) : *Buffer+Length
  Length = PokeS(*Buffer, "Server: Atomic Web Server 0.2b"+EOL$)      : *Buffer+Length
  Length = PokeS(*Buffer, "Content-Length: "+Str(DataLength)+EOL$)    : *Buffer+Length
  Length = PokeS(*Buffer, "Content-Type: "+ContentType$+EOL$)         : *Buffer+Length
  Length = PokeS(*Buffer, EOL$)                                       : *Buffer+Length

  ; Length = PokeS(*Buffer, "Last-modified: Thu, 27 Jun 1996 16:40:50 GMT"+Chr(13)+Chr(10)  , *Buffer) : *Buffer+Length
  ; Length = PokeS(*Buffer, "Accept-Ranges: bytes"+EOL$                 , *Buffer) : *Buffer+Length
  ; Length = PokeS(*Buffer, "Connection: close"+EOL$) : *Buffer+Length

  ProcedureReturn *Buffer
EndProcedure


ProcessRequest:

  a$ = PeekS(*Buffer)
  
  If Left(a$, 3) = "GET"

    MaxPosition = FindString(a$, Chr(13), 5)
    Position = FindString(a$, " ", 5)
    If Position  0
          If *t\a = '/' : *t\a = '\' : EndIf
          *t+1
        Wend
      EndIf

      ; Test if the file exists, and if not display the error message
      ;   

      If ReadFile(0, BaseDirectory$+RequestedFile$)
        MessageRequester("Ca sent bon !","Ca sent bon !",0)
      
        FileLength = Lof()

        Select Right(RequestedFile$,4)
          Case ".gif"
            ContentType$ = "image/gif"

          Case ".jpg"
            ContentType$ = "image/jpeg"

          Case ".txt"
            ContentType$ = "text/plain"

          Case ".zip"
            ContentType$ = "application/zip"

          Default
            ContentType$ = "text/html"

        EndSelect
        
        *FileBuffer   = AllocateMemory(1, FileLength+200, 0)
        *BufferOffset = BuildRequestHeader(*FileBuffer, FileLength, ContentType$)

        ReadData(*BufferOffset, FileLength)

        CloseFile(0)
 
        SendNetworkData(ClientID, *FileBuffer, *BufferOffset-*FileBuffer+FileLength)
        FreeMemory(1)
      Else
        If ReadFile(0, BaseDirectory$+"AtomicWebServer_Error.html")
          FileLength = Lof()
          ContentType$ = "text/html"

          *FileBuffer   = AllocateMemory(1, FileLength+200, 0)
          *BufferOffset = BuildRequestHeader(*FileBuffer, FileLength, ContentType$)

          ReadData(*BufferOffset, FileLength)
          CloseFile(0)
   
          SendNetworkData(ClientID, *FileBuffer, *BufferOffset-*FileBuffer+FileLength)
          FreeMemory(1)
        EndIf
      EndIf
  EndIf

Return
best regards
Joseph

(PureBasic Registered User)

Posted: Thu Oct 03, 2002 7:56 pm
by BackupUser
Restored from previous forum. Originally posted by Berikco.

Hi Joseph,

Looks like you want to put some CGI in Atomic Web Server.
You must not add code in the GET routine, must create POST routine.

First save this in index.html

Code: Select all

CGI Example



Parameter




Here is example of The server, hope this is what you like to do.

Code: Select all

;
; ------------------------------------------------------------
;
;       Atomic Web Server in PureBasic by AlphaSND
;
;           (c) 2001 - Fantaisie Software
;
; ------------------------------------------------------------
;
; 25/03/2001
;   Added path relative feature. It can be started everywhere
;   Added the window to kill it easely
;
; 19/03/2001
;   Added some new features (clients closed automatically)
;
; 17/03/2001
;   First version.
;

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf

Port = 80
BaseDirectory$ = "www/"
DefaultPage$   = "Index.html"
AtomicTitle$   = "Atomic Web Server v1.0"

Global EOL$

EOL$ = Chr(13)+Chr(10)

*Buffer = AllocateMemory(0, 10000, 0)

If CreateNetworkServer(Port)

  OpenWindow(0, 100, 200, 230, 0, #PB_Window_SystemMenu, "Atomic Web Server (Port "+Str(Port)+")")
  
  Repeat
    
    WEvent.l = WindowEvent()
    SEvent.l = NetworkServerEvent()
  
    If WEvent = #PB_EventCloseWindow
      Quit = 1
    EndIf

    If SEvent
      ClientID.l = NetworkClientID()
  
      Select SEvent
      
        Case 1  ; When a new client has been connected...
          
        Case 4  ; When a client has closed the connection...
  
        Default
          RequestLength.l = ReceiveNetworkData(ClientID, *Buffer, 2000)
          Gosub ProcessRequest
          
      EndSelect

    Else
      Delay(20)  ; Don't stole the whole CPU !
    EndIf
    
  Until Quit = 1 
    
  CloseNetworkServer()
Else
  MessageRequester(AtomicTitle$, "Error: can't create the server (port in use ?).", 0)
EndIf
  
End 



Procedure.l BuildRequestHeader(*Buffer, DataLength.l, ContentType$)

  Length = PokeS(*Buffer, "HTTP/1.1 200 OK"+EOL$)                     : *Buffer+Length
  Length = PokeS(*Buffer, "Date: Wed, 07 Aug 1996 11:15:43 GMT"+EOL$) : *Buffer+Length
  Length = PokeS(*Buffer, "Server: Atomic Web Server 0.2b"+EOL$)      : *Buffer+Length
  Length = PokeS(*Buffer, "Content-Length: "+Str(DataLength)+EOL$)    : *Buffer+Length
  Length = PokeS(*Buffer, "Content-Type: "+ContentType$+EOL$)         : *Buffer+Length
  Length = PokeS(*Buffer, EOL$)                                       : *Buffer+Length

  ; Length = PokeS(*Buffer, "Last-modified: Thu, 27 Jun 1996 16:40:50 GMT"+Chr(13)+Chr(10)  , *Buffer) : *Buffer+Length
  ; Length = PokeS(*Buffer, "Accept-Ranges: bytes"+EOL$                 , *Buffer) : *Buffer+Length
  ; Length = PokeS(*Buffer, "Connection: close"+EOL$) : *Buffer+Length

  ProcedureReturn *Buffer
EndProcedure


ProcessRequest:

  a$ = PeekS(*Buffer)
  If Left(a$, 3) = "GET"

    MaxPosition = FindString(a$, Chr(13), 5)
    Position = FindString(a$, " ", 5)
    If Position  0
          If *t\a = '/' : *t\a = '\' : EndIf
          *t+1
        Wend
      EndIf

      ; Test if the file exists, and if not display the error message
      ;   
      If ReadFile(0, BaseDirectory$+RequestedFile$)
        ;MessageRequester("Ca sent bon !","Ca sent bon !",0)
      
        FileLength = Lof()

        Select Right(RequestedFile$,4)
          Case ".gif"
            ContentType$ = "image/gif"

          Case ".jpg"
            ContentType$ = "image/jpeg"

          Case ".txt"
            ContentType$ = "text/plain"

          Case ".zip"
            ContentType$ = "application/zip"

          Default
            ContentType$ = "text/html"

        EndSelect
        
        *FileBuffer   = AllocateMemory(1, FileLength+200, 0)
        *BufferOffset = BuildRequestHeader(*FileBuffer, FileLength, ContentType$)

        ReadData(*BufferOffset, FileLength)

        CloseFile(0)
 
        SendNetworkData(ClientID, *FileBuffer, *BufferOffset-*FileBuffer+FileLength)
        FreeMemory(1)
      Else
        If ReadFile(0, BaseDirectory$+"AtomicWebServer_Error.html")
          FileLength = Lof()
          ContentType$ = "text/html"

          *FileBuffer   = AllocateMemory(1, FileLength+200, 0)
          *BufferOffset = BuildRequestHeader(*FileBuffer, FileLength, ContentType$)

          ReadData(*BufferOffset, FileLength)
          CloseFile(0)
   
          SendNetworkData(ClientID, *FileBuffer, *BufferOffset-*FileBuffer+FileLength)
          FreeMemory(1)
        EndIf
      EndIf
  ElseIf Left(a$, 4) = "POST" ;; here is extra code ------------------
    Repeat
      in= FindString(a$,EOL$,0)
      If in
        Debug Left(a$,in-1)
      EndIf
      a$=Mid(a$,in+2,Len(a$))  
    Until in=0
  EndIf

Return


Regards,

Berikco

http://www.benny.zeb.be

Posted: Fri Oct 04, 2002 8:26 am
by BackupUser
Restored from previous forum. Originally posted by Joseph.

Hello Berikco
thank you very much! Yes, that is exactly what i was wishing to add, some cgi feature to the atomic web server
I tried you modification but to get the EXE actually running I had to add (see below the code section) something like:
RunProgram("c:\myprog\WWW\cgi\purecgi.exe","",1)
otherwise i get only the debug messages and no exe running.
Is that correct or you suggest something else?

thanks again for your excellent help


ElseIf Left(a$, 4) = "POST" ;; here is extra code ------------------
Repeat
in= FindString(a$,EOL$,0)
If in
Debug Left(a$,in-1)
EndIf
a$=Mid(a$,in+2,Len(a$))
Until in=0
; --- launch the EXE ---
RunProgram("c:\myprog\WWW\cgi\purecgi.exe","",1)
EndIf


best regards
Joseph

(PureBasic Registered User)

Posted: Fri Oct 04, 2002 8:59 am
by BackupUser
Restored from previous forum. Originally posted by Berikco.
Originally posted by Joseph

Hello Berikco
thank you very much! Yes, that is exactly what i was wishing to add, some cgi feature to the atomic web server
I tried you modification but to get the EXE actually running I had to add (see below the code section) something like:
RunProgram("c:\myprog\WWW\cgi\purecgi.exe","",1)
otherwise i get only the debug messages and no exe running.
Is that correct or you suggest something else?

thanks again for your excellent help


ElseIf Left(a$, 4) = "POST" ;; here is extra code ------------------
Repeat
in= FindString(a$,EOL$,0)
If in
Debug Left(a$,in-1)
EndIf
a$=Mid(a$,in+2,Len(a$))
Until in=0
; --- launch the EXE ---
RunProgram("c:\myprog\WWW\cgi\purecgi.exe","",1)
EndIf


best regards
Joseph

(PureBasic Registered User)
This is correct for runing exe, i only dit the debug messages, wanted something left to do for you :)
If you want to work with password, just read networkdata again, the parameter from the form is waiting in the buffer, now you only see the http header. 'content lenght' is the number of bytes waiting.

Regards,

Berikco

http://www.benny.zeb.be