#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d; Default AU3CheckUsed when checking syntax (CTRL+F5) #include #include #include "HTTPAPI.au3" Const $HTTP_HOST = "http://127.0.0.1:9000", _ $HTTP_PATH = "/a3server" Global $giServerSessionId = 0, _ $giUrlGroupId = 0 Global $ghRequestQueue = -1 Global $gaUrls[0] main() ;========================================================================== Func main() httpapi_udf_startup() httpapi_initialize() create_server_session() create_url_group() create_request_queue() bind_request_queue_to_url_group() add_url_to_url_group($HTTP_HOST & $HTTP_PATH) ConsoleWrite("HTTP server is listening on the following URL(s):" & @CRLF) ConsoleWrite(_ArrayToString($gaUrls, @CRLF) & @CRLF) process_requests() EndFunc Func httpapi_udf_startup($bDebug = False) ;Initialize UDF _HTTPAPI_Startup($bDebug) If @error Then MsgBox($MB_ICONERROR, "ERROR", _ "_HTTPAPI_Startup failed with @error =" & @error & " @extended = " & @extended & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) Exit 1 EndIf EndFunc Func httpapi_initialize() ;Intialize the API _HTTPAPI_HttpInitialize() If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpInitialize ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) Exit 1 EndIf OnAutoItExitRegister(httpapi_terminate) EndFunc Func httpapi_terminate() ;Terminate the API _HTTPAPI_HttpTerminate() If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpTerminate ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) EndIf EndFunc Func create_server_session() ;Create a server session $giServerSessionId = _HTTPAPI_HttpCreateServerSession() If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpCreateServerSession ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) Exit 1 EndIf OnAutoItExitRegister(close_server_session) EndFunc Func close_server_session() ;Close server session _HTTPAPI_HttpCloseServerSession($giServerSessionId) If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpCloseServerSession ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) EndIf EndFunc Func create_url_group() ;Create a URL group $giUrlGroupId = _HTTPAPI_HttpCreateUrlGroup($giServerSessionId) If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpCreateUrlGroup ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) Exit 1 EndIf OnAutoItExitRegister(close_url_group) EndFunc Func close_url_group() ;Close server session _HTTPAPI_HttpCloseUrlGroup($giUrlGroupId) If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpCloseUrlGroup ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) EndIf EndFunc Func create_request_queue() ;Create a new request queue $ghRequestQueue = _HTTPAPI_HttpCreateRequestQueue() If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpCreateRequestQueue ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) Exit 1 EndIf OnAutoItExitRegister(close_request_queue) EndFunc Func close_request_queue() ;Shut down request queue _HTTPAPI_HttpShutdownRequestQueue($ghRequestQueue) If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpShutdownRequestQueue ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) EndIf EndFunc Func bind_request_queue_to_url_group() Local $tBindingInfo = DllStructCreate($__HTTPAPI_gtagHTTP_BINDING_INFO) ;Set Binding Info $tBindingInfo.Flags = $__HTTPAPI_HTTP_PROPERTY_FLAG_PRESENT $tBindingInfo.RequestQueueHandle = $ghRequestQueue ;Bind request _HTTPAPI_HttpSetUrlGroupProperty( _ $giUrlGroupId, _ $__HTPPAPI_HttpServerBindingProperty, _ DllStructGetPtr($tBindingInfo), _ DllStructGetSize($tBindingInfo)) If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpSetUrlGroupProperty ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) Exit 1 EndIf OnAutoItExitRegister(unbind_request_queue_from_url_group) EndFunc Func unbind_request_queue_from_url_group() Local $tBindingInfo = DllStructCreate($__HTTPAPI_gtagHTTP_BINDING_INFO) ;Set Binding Info $tBindingInfo.Flags = 0 $tBindingInfo.RequestQueueHandle = Null ;Bind request _HTTPAPI_HttpSetUrlGroupProperty( _ $giUrlGroupId, _ $__HTPPAPI_HttpServerBindingProperty, _ DllStructGetPtr($tBindingInfo), _ DllStructGetSize($tBindingInfo)) If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpSetUrlGroupProperty ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) EndIf EndFunc Func add_url_to_url_group($sUrl) ;Add url to url group _HTTPAPI_HttpAddUrlToUrlGroup($giUrlGroupId, $sUrl) If @error Then MsgBox($MB_ICONERROR, "_HttpAddUrlToUrlGroup ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) Exit 1 EndIf ;Store URL _ArrayAdd($gaUrls, $sUrl) OnAutoItExitRegister(remove_all_urls_from_url_group) EndFunc Func remove_all_urls_from_url_group() ;Remove all URLS from URL Group _HTTPAPI_HttpRemoveUrlFromUrlGroup($giUrlGroupId, "", $__HTTPAPI_HTTP_URL_FLAG_REMOVE_ALL) If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpSetUrlGroupProperty ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) EndIf EndFunc Func process_requests() Local $tBuffer = "", $tRequest = "" ;, $tDataChunk = "", $tHeader = "" Local $sPath = "" ;Wait for requests While 1 ;Receive request $tBuffer = _HTTPAPI_HttpReceiveHttpRequest($ghRequestQueue) If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpReceiveHttpRequest ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) Exit 1 EndIf ;Create structs for request and body $tRequest = DllStructCreate($__HTTPAPI_gtagHTTP_REQUEST_V2 & StringFormat("byte body[%i];", $__HTTPAPI_REQUEST_BODY_SIZE), DllStructGetPtr($tBuffer)) ;If stop requested $sPath = _WinAPI_GetString($tRequest.pAbsPath) If StringRight($sPath, 1) = "/" Then StringTrimRight($sPath, 1) If $sPath = $HTTP_PATH & "/stop" Then ExitLoop ;Process request based on verb Switch $tRequest.Verb Case $__HTTPAPI_HttpVerbGET process_get_request($tBuffer) Case $__HTTPAPI_HttpVerbPOST process_post_request($tBuffer) Case Else EndSwitch ;Delete request resources $tBuffer = 0 Sleep(100) WEnd EndFunc Func process_get_request(ByRef $tBuffer) Local $tRequest = "" Local $aHeaders[0] Local $sPath = "", $sMsg = "", $sReason, $sCmdOutput = "" Local $iStatusCode = 0 ;Create structs for request and body $tRequest = DllStructCreate($__HTTPAPI_gtagHTTP_REQUEST_V2 & StringFormat("byte body[%i];", $__HTTPAPI_REQUEST_BODY_SIZE), DllStructGetPtr($tBuffer)) ;Display request info ConsoleWrite("GET request received" & @CRLF) ConsoleWrite("Request ID = " & Hex($tRequest.RequestId) & @CRLF) ConsoleWrite("Request struct size = " & DllStructGetSize($tRequest) & @CRLF) ConsoleWrite("Bytes received = " & $tRequest.BytesReceived & @CRLF) ConsoleWrite("Full URL = " & _WinAPI_GetString($tRequest.pFullUrl) & @CRLF) ConsoleWrite("Host = " & StringRegExpReplace(_WinAPI_GetString($tRequest.pHost), "^([^/]+).*", "\1") & @CRLF) ConsoleWrite("AbsPath = " & _WinAPI_GetString($tRequest.pAbsPath) & @CRLF) ConsoleWrite("QueryString = " & _WinAPI_GetString($tRequest.pQueryString) & @CRLF) ConsoleWrite("Verb = " & $tRequest.verb & @CRLF) ConsoleWrite("EntityChunkCount = " & $tRequest.EntityChunkCount & @CRLF) ConsoleWrite("UnknownHeaderCount = " & $tRequest.UnknownHeaderCount & @CRLF) ;Display headers $aHeaders = _HTTPAPI_GetRequestHeaders(DllStructGetPtr($tRequest, "UnknownHeaderCount")) If IsArray($aHeaders) Then ConsoleWrite("Request Headers" & @CRLF) For $i = 0 To UBound($aHeaders) - 1 ConsoleWrite(StringFormat("> %s: %s", $aHeaders[$i][0], $aHeaders[$i][1]) & @CRLF) Next EndIf ;Send response $sPath = _WinAPI_GetString($tRequest.pAbsPath) If StringRight($sPath, 1) = "/" Then $sPath = StringTrimRight($sPath, 1) ;Remove trailing / Switch $sPath Case $HTTP_PATH $iStatusCode = 200 $sReason = "OK" $sMsg = "

GET request received!

Hello from the AutoIt HTTP Server." Case $HTTP_PATH & "/test1" $iStatusCode = 200 $sReason = "OK" $sMsg = "

GET request received!

Test1 request received." Case $HTTP_PATH & "/ipconfig" $iStatusCode = 200 $sReason = "OK" $sCmdOutput = cmd_capture("ipconfig /all") If @error Then $sMsg = "

An error occured!

@error = " & @error Else $sMsg = "

Output

" & $sCmdOutput & "
" EndIf Case Else $iStatusCode = 404 $sReason = "Not Found" $sMsg = "

Not Found


HTTP Error 404. The requested resource is not found.

" EndSwitch _HTTPAPI_HttpSendHttpResponse($ghRequestQueue, $tRequest.RequestId, $iStatusCode, $sReason, $sMsg) If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpSendHttpResponse ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) Exit 1 EndIf EndFunc Func process_post_request(ByRef $tBuffer) Local $tRequest = "", $tDataChunk = "" Local $aHeaders Local $sBody = "" ;Create structs for request and body $tRequest = DllStructCreate($__HTTPAPI_gtagHTTP_REQUEST_V2 & StringFormat("byte body[%i];", $__HTTPAPI_REQUEST_BODY_SIZE), DllStructGetPtr($tBuffer)) ;Display something ConsoleWrite("POST request received" & @CRLF) ConsoleWrite("Request struct size = " & DllStructGetSize($tRequest) & @CRLF) ConsoleWrite("Bytes received = " & $tRequest.BytesReceived & @CRLF) ConsoleWrite("Full URL = " & _WinAPI_GetString($tRequest.pFullUrl) & @CRLF) ConsoleWrite("Host = " & StringRegExpReplace(_WinAPI_GetString($tRequest.pHost), "^([^/]+).*", "\1") & @CRLF) ConsoleWrite("AbsPath = " & _WinAPI_GetString($tRequest.pAbsPath) & @CRLF) ConsoleWrite("QueryString = " & _WinAPI_GetString($tRequest.pQueryString) & @CRLF) ConsoleWrite("Verb = " & $tRequest.verb & @CRLF) ConsoleWrite("EntityChunkCount = " & $tRequest.EntityChunkCount & @CRLF) ;Display headers $aHeaders = _HTTPAPI_GetRequestHeaders(DllStructGetPtr($tRequest, "UnknownHeaderCount")) If IsArray($aHeaders) Then ConsoleWrite("Request Headers" & @CRLF) For $i = 0 To UBound($aHeaders) - 1 ConsoleWrite(StringFormat("> %s: %s", $aHeaders[$i][0], $aHeaders[$i][1]) & @CRLF) Next EndIf ;Display body If $tRequest.pEntityChunks >= 1 Then $tDataChunk = DllStructCreate($__HTTPAPI_gtagHTTP_DATA_CHUNK, $tRequest.pEntityChunks) If $tDataChunk.DataChunkType = $__HTPPAPI_HttpDataChunkFromMemory Then $tDataChunk = DllStructCreate($__HTTPAPI_gtagHTTP_DATA_CHUNK_FROM_MEMORY, $tRequest.pEntityChunks) $sBody = _WinAPI_GetString($tDataChunk.pBuffer, False) ConsoleWrite("DataChunkType = " & $tDataChunk.DataChunkType & @CRLF) ConsoleWrite("DataChunkLength = " & $tDataChunk.pBufferLength & @CRLF) ConsoleWrite("Request Body = " & $sBody & @CRLF) EndIf EndIf ;Send response _HTTPAPI_HttpSendHttpResponse($ghRequestQueue, $tRequest.RequestId, _ 200, "OK", _ "POST request received! Hello from the AutoIt HTTP Server." & _ "

" & _ "You posted:
" & _ "
" & $sBody & "
") If @error Then MsgBox($MB_ICONERROR, "_HTTPAPI_HttpSendHttpResponse ERROR", _ "@error =" & @error & " @extended = " & @extended & @CRLF & @CRLF & _ _HTTPAPI_GetLastErrorMessage()) Exit 1 EndIf EndFunc Func cmd_capture($sCmd, $sWorkingDir = @WorkingDir) Local $iPID = 0 Local $sOutput = "" ;resolve defaults If $sWorkingDir = Default Then $sWorkingDir = @WorkingDir ;execute command $iPID = Run(@ComSpec & ' /c ' & $sCmd, $sWorkingDir, @SW_HIDE, $STDERR_MERGED) If @error Then ConsoleWrite("Error: Unable to execute command - " & $sCmd & @CRLF) Return SetError(1, 0, "") EndIf ;wait for process to end ProcessWaitClose($iPID) ;get output $sOutput = StdoutRead($iPID) ;if no output, set @error and return empty string If $sOutput = "" Then Return SetError(2, 0, "") ;return output Return $sOutput EndFunc