Jump to content
wraithdu

AutoIt CGI Handler: AuCGI

Recommended Posts

wraithdu

New and updated version of AuCGI.

I'd like to thank theguy0000 for the original code, ptrex for his LightTPD instructions, and JRowe for his enthusiasm, help, and input, and for the page he is putting together for this project at AutoIt.me.

We've been working the last few days to revamp and optimize this project. We've stripped the CGI handler down to its core functionality and removed the requirement to include 'Web.au3'. The core functions of Web.au3 are now dynamically included. Other functionality will be made available as includable UDF 'modules'. Better documentation is also forthcoming.

See JRowe's site for a little tutorial on how to get started with this. Documentation and other pertinent info will also be available there.

The attached ZIP has the sources for AuCGI, Web.au3, as well as the LightTPD Server Control helper app.

Please note: Web.au3 is not to be included anywhere. It is available simply as an easy place to update or add to the core functions. This code is dynamically included by AuCGI. So just put Web.au3 somewhere safe if you want to reference it, but otherwise forget it even exists.

2011/05/11 - updated AuCGI to v2.0.0.3 to fix the source script path error (thanks Cynagen)

2010/09/08 - updated AuCGI to v2.0.0.2 with hopeful IIS compatibility

2010/04/02 - updated Server Control to v 1.0.1.2

2010/03/10 - updated AuCGI to v2.0.0.1

AuCGI.zip

Edited by wraithdu

Share this post


Link to post
Share on other sites
JRowe

Feel free to post here if anything is incorrect or unclear. Big thanks to Ptrex, theguy0000, and all the contributors who helped create this. Suggestions and input are welcome!

Share this post


Link to post
Share on other sites
JRowe

If you use AuCGI for anything, it would be nice if you used the Posted Image tag somewhere on your page.

Here's the tutorial:

AuCGI is easy to use. It's best used with LightTPD, or more specifically, the Windows version of the LightTPD server, called WLMP.

http://code.google.com/p/wlmp-project/

Download LightTPD from here: http://wlmp-project.googlecode.com/files/LightTPD-1.4.26-1-Win32-SSL.exe

Install LightTPD to C:\LightTPD

Download AuCGI.exe

Create a folder called AUCGI in the LightTPD directory, and place the AuCGI.exe there.

C:\LightTPD\AUCGI\AuCGI.exe

Download AuCGIFiles.zip and unzip.

Place lighttpd-inc.conf in the C:\LightTPD\conf directory

Place test.web in the C:\LightTPD\htdocs directory

Place Start.bat in the C:\Lighttpd directory

Double Click on Start.bat to launch Lighttpd.

Access your webserver at http://localhost/

Check out the AuCGI demo at http://localhost/test.web !

Share this post


Link to post
Share on other sites
Shafayat

Great job. I am certainly going to try it. It looks very professional. :mellow:


[Not using this account any more. Using "iShafayet" instead]

Share this post


Link to post
Share on other sites
ptrex

@wraithdu

Good to see this project is still alive and kicking.

But I did a quick test using this index.au3 file.

Which I use for testing au3 functions in AuCGI.

And it througs up error an error at line 191 ?!

Index.zip

It does run properly in the old AuCGI version.

Rgds,

ptrex

Share this post


Link to post
Share on other sites
JRowe

We got rid of the requirement for the shebang. _WebCounter and _MsgBox are no longer included.

Everything is reduced, (almost) to the bare minimum necessary to make it work. Web.au3 contains the functions still present in the handler.

The usage is slightly different from what it used to be. Now things are much cleaner. You'll have to include the source for old functions such as _webCounter() or _msgBox() because they are no longer included, nor are the rss feeds, a few helper functions, and so on.

Try this:

<?au3 _standardHeader() ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
 <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
 <title>Test</title>
</head>

<body>
<?au3
    echo("<br></br>")
    echo("Hello World - from LightPD")
    echo("<br></br>")
    echo(@ScriptName & "<br></br>" & @AutoItVersion)
    echo("<br></br>")
?>
</body>
</html>

Bonus: Add "".html" => "C:/LightTPD/AUCGI/AuCGI.exe"," to the cgi.assign block in lighttpd-inc.conf and you can embed <?au3 ?> inside normal html.

You need to include <?au3 _standardHeader() ?> at the top of the html document. Here's a link that explains why. It signifies to the browser what type of behavior is expected and so forth.

Aside from that requirement, you should be able to use any valid html or xhtml document as a web application.

@ScriptName will return the temporary script name, rather than the document name. If you want the document name, use $_SCRIPT_NAME.

Use this to see all the available information:

<?au3 _standardHeader() ?>
<html>
<body>
<?au3
    echo("Version: " & $AuCGI_version & "<br />")
        echo("Remote Address: " & $_REMOTE_ADDR & "<br />")
        echo("Version: " & $_ACCEPT_LANGUAGE & "<br />")
        echo("Host: " & $_HOST & "<br />")
        echo("Charset: " & $_ACCEPT_CHARSET & "<br />")
        echo("User Agent: " & $_USER_AGENT & "<br />")
        echo("Server Software: " & $_SERVER_SOFTWARE & "<br />")
        echo("Server Name: " & $_SERVER_NAME & "<br />")
        echo("Server Protocol: " & $_SERVER_PROTOCOL & "<br />")
        echo("Server Port: " & $_SERVER_PORT & "<br />")
        echo("Script Name: " & $_SCRIPT_NAME & "<br />")
        echo("HTTPS: " & $_HTTPS & "<br />")
        echo("Document Root: " & $_DOCUMENT_ROOT & "<br />")
        echo("HTTP Referrer: " & $_HTTP_REFERER & "<br />")
        echo("Path: " & $_PATH & "<br />")
        echo("Remote Host: " & $_REMOTE_HOST & "<br />")
        echo("Remote Port: " & $_REMOTE_PORT & "<br />")
        echo("Remote User: " & $_REMOTE_USER & "<br />")
        echo("Request Method: " & $_REQUEST_METHOD & "<br />")
        echo("Request URI: " & $_REQUEST_URI & "<br />")
        echo("Script Filename: " & $_SCRIPT_FILENAME & "<br />")
        echo("Server Admin: " & $_SERVER_ADMIN & "<br />")
?>
</body>
</html>

We got rid of almost everything that wasn't necessary for this to be easily used and expanded on. From now on, if someone writes an RSS handler or a _msgBox() widget, it should be included as a UDF or a demo, rather than added on to the source. The only things that should change in the source for the AuCGI are optimizations, bug fixes, and additions determined to be essential to the operation of an AuCGI handler.

This makes the AuCGI.exe load and execute faster and take up less memory on the server.

Share this post


Link to post
Share on other sites
ptrex
wraithdu

Yeah dude, nice explanation :mellow:

Share this post


Link to post
Share on other sites
Shafayat

Here is a little contribution that I like to call AuCGI Server Controller. Now you can forget the stupid "Start.bat" and use this script (preferably compiled) instead. This is fast and cooler. Best of all it can minimize to tray so, no annoying windows. It reads stdoutputs so, you get every message.

Here is a screenshot:

post-23819-12680336090289_thumb.png

Here is the code:

#include <Constants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
TraySetIcon(@ScriptDir & "\LightTPD.exe")
Opt("TrayOnEventMode", 1)
Opt("TrayMenuMode", 1) ; Default tray menu items (Script Paused/Exit) will not be shown.
TraySetOnEvent($TRAY_EVENT_PRIMARYUP, "gRestore")

$Form1 = GUICreate("auCGI Server Controller 1.01", 608, 426, 197, 121)
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
GUISetOnEvent($GUI_EVENT_MINIMIZE, "Form1Minimize")
$gEdit = GUICtrlCreateEdit("", 0, 64, 625, 377, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_READONLY, $ES_WANTRETURN, $WS_HSCROLL, $WS_VSCROLL))
GUICtrlSetData($gEdit, "Nothing Yet ....")
$gStart = GUICtrlCreateButton("Start", 8, 8, 113, 49)
GUICtrlSetOnEvent($gStart, "gStartClick")
$gEnd = GUICtrlCreateButton("End", 128, 8, 113, 49)
GUICtrlSetOnEvent($gEnd, "gEndClick")
$gRefresh = GUICtrlCreateButton("Refresh", 400, 8, 113, 49)
GUICtrlSetOnEvent($gRefresh, "gRefreshClick")
$gStatus = GUICtrlCreateLabel("Status: Disabled", 520, 40, 81, 17)
GUICtrlSetColor($gStatus, 0xFF0000)
GUISetState(@SW_SHOW)


Global $PID = 0
;~ Global $hAdlib

While 1
    Sleep(100)
WEnd

Func Form1Close()
    gEndClick()
    Exit
EndFunc   ;==>Form1Close
Func Form1Minimize()
    GUISetState(@SW_HIDE)

EndFunc   ;==>Form1Minimize
Func gRestore()
    GUISetState(@SW_SHOW)

EndFunc   ;==>gRestore
Func gEndClick()
    AdlibUnRegister("CheckStdOut")
    If $PID = 0 Then
        GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & " Error: Server is not running... ")
    Else
        ProcessClose($PID)
        $PID = 0
        GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & " ===================== SERVER STOPPED ===================== ")
        GUICtrlSetData($gStatus, "Status: Disabled")
        GUICtrlSetColor($gStatus, 0xFF0000)
    EndIf

    ;AdlibUnRegister("CheckStdOut")
EndFunc   ;==>gEndClick

Func gRefreshClick()

EndFunc   ;==>gRefreshClick

Func gStartClick()
    $PID = Run("C:\LightTPD\lighttpd.exe -f conf\lighttpd-inc.conf -m lib -D", "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    AdlibRegister("CheckStdOut")
    GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & " ===================== SERVER STARTED ===================== ")
    GUICtrlSetData($gStatus, "Status: Enabled")
    GUICtrlSetColor($gStatus, 0x00FF00)
EndFunc   ;==>gStartClick

Func CheckStdOut()
    Local $line1, $line2, $err = 0
    $line1 = StdoutRead($PID)
    If @error Then $err = $err + 1
    $line2 = StderrRead($PID)
    If @error Then $err = $err + 1
    If $err = 2 Then TerminateLib()


    If $line1 <> '' Then
        $line1 = StringReplace($line1, @CR, @CRLF)
        $line1 = StringReplace($line1, @LF, @CRLF)
        GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & $line1)
    EndIf
    If $line2 <> '' Then
        $line2 = StringReplace($line2, @CR, @CRLF)
        $line2 = StringReplace($line2, @LF, @CRLF)
        GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & $line2)
    EndIf


EndFunc   ;==>CheckStdOut
Func TerminateLib()
    MsgBox(0, "", "bye")
    GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & " ===================== SERVER STOPPED ===================== ")
    GUICtrlSetData($gStatus, "Status: Disabled")
    GUICtrlSetColor($gStatus, 0xFF0000)
    AdlibUnRegister("CheckStdOut")
EndFunc   ;==>TerminateLib

If you find it worthy, I'd like to see it included in the official distribution from Autoit.me

P.S: Not unlike start.bat it will only work when run from C:\LightTPD directory.

Best Regards

Shafayat

AuCGI Server Controller.au3

Edited by Shafayat

[Not using this account any more. Using "iShafayet" instead]

Share this post


Link to post
Share on other sites
wraithdu

Nice idea. Here's a cleaned up version with some bug fixes, more user friendly options like tray menu items and tips, and command line support.

@JRowe

Want to include this?

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_Comment=AuCGI Server Controller
#AutoIt3Wrapper_Res_Description=AuCGI Server Controller
#AutoIt3Wrapper_Res_Fileversion=1.0.1.0
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
#AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
;=======================================
; Original Author: Shafayat
; Updated by: Erik Pilsits (wraithdu)
;=======================================

#include <Constants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Opt("GUIOnEventMode", 1)
Opt("GUIEventOptions", 1) ; just send min/max/close notifications
Opt("TrayOnEventMode", 1)
Opt("TrayMenuMode", 3) ; default tray menu items (Script Paused/Exit) will not be shown

TraySetIcon(@ScriptDir & "\LightTPD.exe")
TrayCreateItem("Start")
TrayItemSetOnEvent(-1, "gStartClick")
TrayCreateItem("Stop")
TrayItemSetOnEvent(-1, "gEndClick")
TrayCreateItem("")
TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "gAppClose")
TraySetOnEvent($TRAY_EVENT_PRIMARYUP, "gRestore")
TraySetClick(8) ; press secondary mouse to show menu
TraySetToolTip("Status: Not Running")

GUICreate("AuCGI Server Controller 1.01", 608, 426, 197, 121)
GUISetOnEvent($GUI_EVENT_CLOSE, "gAppClose")
GUISetOnEvent($GUI_EVENT_MINIMIZE, "gMinimize")
Global $gEdit = GUICtrlCreateEdit("", 0, 64, 625, 377, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_READONLY, $ES_WANTRETURN, $WS_HSCROLL, $WS_VSCROLL))
GUICtrlSetBkColor($gEdit, 0xFFFFFF)
GUICtrlSetData($gEdit, "AuCGI Server Controller 1.01" & @CRLF)
GUICtrlCreateButton("Start", 8, 8, 113, 49)
GUICtrlSetOnEvent(-1, "gStartClick")
GUICtrlCreateButton("Stop", 128, 8, 113, 49)
GUICtrlSetOnEvent(-1, "gEndClick")
Global $gStatus = GUICtrlCreateLabel("Status: Not Running", 490, 40, 120, 17)
GUICtrlSetColor($gStatus, 0xFF0000)

Global $PID = 0

If $CmdLine[0] > 0 Then
    Switch $CmdLine[1]
        Case "-start"
            ; minimized, start server
            gStartClick()
        Case "-startshow"
            ; show gui, start server
            GUISetState()
            gStartClick()
        Case "-min"
            ; minimized, server not started
        Case Else
            ; show GUI, server not started
            GUISetState()
    EndSwitch
Else
    GUISetState()
EndIf

While 1
    Sleep(1000)
WEnd

Func gAppClose()
    If $PID Then ProcessClose($PID)
    Exit
EndFunc   ;==>gAppClose

Func gMinimize()
    GUISetState(@SW_HIDE)
EndFunc   ;==>gMinimize

Func gRestore()
    GUISetState(@SW_SHOW)
EndFunc   ;==>gRestore

Func gEndClick()
    If Not $PID Then
        GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & " Error: Server is not running... ")
    Else
        ProcessClose($PID)
        $PID = 0
    EndIf
EndFunc   ;==>gEndClick

Func gStartClick()
    $PID = Run('"' & @ScriptDir & '\LightTPD.exe" -f conf/lighttpd-inc.conf -m lib -D', @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    AdlibRegister("CheckStdOut", 1000)
    GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & " ===================== SERVER STARTED ===================== ")
    GUICtrlSetData($gStatus, "Status: Running [" & $PID & "]")
    GUICtrlSetColor($gStatus, 0x00FF00)
    TraySetToolTip("Status: Running [" & $PID & "]")
EndFunc   ;==>gStartClick

Func CheckStdOut()
    Local $err = 0
    Local $line1 = StdoutRead($PID)
    If @error Then $err += 1
    Local $line2 = StderrRead($PID)
    If @error Then $err += 1
    If $err = 2 Then
        gTerminateLib()
        Return
    EndIf

    If $line1 <> '' Then
        $line1 = StringReplace(StringReplace($line1, @LF, @CRLF), @CR, @CRLF)
        GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & $line1)
    EndIf
    If $line2 <> '' Then
        $line2 = StringReplace(StringReplace($line2, @LF, @CRLF), @CR, @CRLF)
        GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & $line2)
    EndIf
EndFunc   ;==>CheckStdOut

Func gTerminateLib()
    GUICtrlSetData($gEdit, GUICtrlRead($gEdit) & @CRLF & " ===================== SERVER STOPPED ===================== ")
    GUICtrlSetData($gStatus, "Status: Not Running")
    GUICtrlSetColor($gStatus, 0xFF0000)
    TraySetToolTip("Status: Not Running")
    AdlibUnRegister("CheckStdOut")
EndFunc   ;==>TerminateLib
Edited by wraithdu

Share this post


Link to post
Share on other sites
JRowe

Looks good to me! Thanks, Shafayat, great idea. I'll bundle it with the downloads and add it to the tutorial.

Share this post


Link to post
Share on other sites
BennyBB

That's rather awesome. We have a school project where we have to build up our own website and most of us are just beginners in Webcoding but with the AuCGI almost everything I was looking for is possible and all this without learning any real server side language such as php or ASP. This fact saved me a lot of time :(

Sadly I didn't find this back in the time I began with AutoIT, It would have safed me a lot of time, work and disappointment.

Just saying it in one sentence : thanks to everyone who has helped to develope this in the past 4 years :mellow:

EDIT: BTW I found a small error. If you use a larger HTML Document without any autoit in it it will cause an ,,unterminates string" and crash.

this is how I fixed it:

Func _parseSource($source)
    Local $idx = 1, $idx2, $lastidx = 1, $parsed = "", $chunk = ""
    Do
        ; get first code snippet
        $idx = StringInStr($source, "<?au3", 0, 1, $idx)
        If $idx Then
            If $idx > $lastidx Then
                ; we have html
                $chunk = StringMid($source, $lastidx, $idx - $lastidx) ; get it
                $parsed &= 'ConsoleWrite("' & StringReplace(StringReplace($chunk, '"', '""'), @CRLF, '" & @CRLF & "') & '")' & @CRLF ; write it
            EndIf
            $idx += 5 ; start of code
            ; get end of code tag
            $idx2 = StringInStr($source, "?>", 0, 1, $idx)
            If $idx2 Then
                ; found end of code
                $chunk = StringMid($source, $idx, $idx2 - $idx) ; get it
                $parsed &= $chunk & @CRLF ; write it
                $lastidx = $idx2 + 2 ; new $lastidx value, set to position after end-code tag
                $idx = $lastidx ; next search start location
            Else
                ; parse error, get out
                _error("Error parsing source.")
            EndIf
        Else
            ; no code sections or last section of html
                        $chunk = StringMid($source, $lastidx) ; get it
            If $chunk Then _ ; check we actually have something this time
                    $splitted = StringSplit($chunk,@CRLF,1)
                    For $b = 1 to $splitted[0] Step 1
                        If StringInStr($splitted[$b],"</html>") > 0 Then
                            ;end of document
                            $parsed &= 'ConsoleWrite("' & StringTrimRight($splitted[$b],StringLen($splitted[$b])-StringInStr($splitted[$b],"</html>",1)) & '/html>")'
                            ExitLoop
                        EndIf
                        $parsed &= 'ConsoleWrite("' & StringReplace($splitted[$b], '"', '""') & '" & @CRLF)' & @CRLF
                        Next
        EndIf
    Until Not $idx
    Return $parsed
EndFunc   ;==>_parseSource

you could check that and if necessary add it to the file in the first post

Edited by BennyBB

Share this post


Link to post
Share on other sites
BasicOs

Congrats JRowe.

I added your Au3 cgi links in our au3 cgi dedicated support subforum for spanish autoit.

http://www.emesn.com/autoitforum/viewforum.php?f=6

Edited by BasicOs

Autoit.es - Foro Autoit en EspaƱol Word visitors Image Clustrmap image: - Football Spanish team - Spanish team: Casillas, Iniesta, Villa, Xavi, Puyol, Campdevilla, etc..Programando en Autoit+Html - Coding Autoit-Html - Arranca programas desde Internet - Preprocesador de Autoit a http

Share this post


Link to post
Share on other sites
wraithdu

@BennyBB

Can you post an html sample that causes your problem? I'll need it to properly fix the problem.

Share this post


Link to post
Share on other sites
wraithdu

Ok, I see the error. I think it's because ConsoleWrite has a fixed length buffer. 64K maybe? I'll implement your fix.

/edit:

After further reflection, I think we were bumping into the interpreter's max single line length (4095 characters) in the temp script. So yes, splitting the lines is the proper solution.

Edited by wraithdu

Share this post


Link to post
Share on other sites
wraithdu

Ok, I've updated the first post with the fix. Thanks BennyBB for the report!

I also included the Server Control source in the zip. Everyone update!

Share this post


Link to post
Share on other sites
Shafayat

Hello

Its me again. I am looking forward to use it seriously in my server :mellow: . I am having a little trouble with file upload. Can you make a quick *.web file (example page) that handles file upload. A very basic one with the HTML file upload control would do.

Best Regards

Shafayat


[Not using this account any more. Using "iShafayet" instead]

Share this post


Link to post
Share on other sites
wraithdu

Good luck on that one. That really has nothing to do with the CGI handler. That's going to be up to the back end code you write to work with the web server to handle an upload. I honestly have no idea where to begin with that. I think that question is better left to its own thread and not here.

Share this post


Link to post
Share on other sites
Shafayat

Well yeah. I just figured that out. Thanks for the heads up.


[Not using this account any more. Using "iShafayet" instead]

Share this post


Link to post
Share on other sites
JRowe

I think that's handled by multipart POST. I'll do some tests and figure out what's what.

http://www.autoit.me/ServerControl.au3

There's the server control app. :mellow:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×