1. Euphoria CGI

Maybe this is a stupid question but as it is that easy to run Euphoria CGI programs is there any good reason not to build an HTML-based cross-platform IDE?

Here is the way I configured CGI on my Apache 2 server as I had difficulties to get CGI scripts to be run with official documentation.

cd /etc/apache2/ 
 
sudo vi conf-available/serve-cgi-bin.conf 
  below folowing line: 
                ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ 
  add following lines: 
                AddHandler exu-file .exu .ex 
                Action exu-file /cgi-bin/runexu.cgi 
 
cd mods-enabled/ 
sudo ln -s ../mods-available/cgi.load  
 
sudo vi /usr/lib/cgi-bin/runexu.cgi 
#!/bin/sh  
#runexu.cgi - wrapper to run a euphoria program without the need for #!  
  
# Naturally, use the path to YOUR exu on your system  
/usr/local/euphoria-4.1.0-Linux-x86/bin/eui $PATH_TRANSLATED  
# END of runexu.cgi 
 
sudo chmod +x /usr/lib/cgi-bin/runexu.cgi 
 
sudo /etc/init.d/apache2 restart 
sudo ln -s myCgiFolder/myCgiSubfolder /var/www/html/myCgiSubfolder 

Of course myCgiFolder, myCgiSubfolder and /usr/local/euphoria-4.1.0-Linux-x86/bin/eui have to be replaced by your own locations. Any Euphoria CGI script under myCgiFolder/myCgiSubfolder can be performed by accessing http://localhost/myCgiSubfolder/scriptName

Jean-Marc

new topic     » topic index » view message » categorize

2. Re: Euphoria CGI

I forgot to mention I'm running Apache2 on Debian 8 (Jessie) on either PC or Raspberry Pi.

new topic     » goto parent     » topic index » view message » categorize

3. Re: Euphoria CGI

Since with HTML5 you can do most things that you can do with a native GUI, it seems that a wrapper would be possible. Can you write a small demo as proof of concept? That would provide a starting point.

new topic     » goto parent     » topic index » view message » categorize

4. Re: Euphoria CGI

I will try. In the mean time, I think I discovered many reasons that make it difficult to build:

  • widgets layout
  • events
  • one script per Web page
  • parameters

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

5. Re: Euphoria CGI

Here is the basic principle of the web display server:

  • The OpenEuphoria program acts as a client to send orders to the display server and as a server to listen for events.
  • Each command (for example Create Button) is sent as a POST request to the Web display server on a dedicated port, let's say 10000.
  • The server updates the page and sets the Refresh field in the header.

When the user submits a form, the client program does not know anything happened, so the server has to send a frame to inform the client program.

The problem is that a browser is needed to display pages. Either we need to write a browser in Euphoria or we need to drive a browser with Euphoria.

Second option needs:

  • either a wrapper on the selenium2 library (www.seleniumhq.org)
  • or to drive Firefox through MozREPL (addons.mozilla.org/fr/firefox/addon/mozrepl)
  • or to drive geckodriver (github.com/mozilla/geckodriver) or chromedriver (sites.google.com/a/chromium.org/chromedriver) via WebDriver's wire protocol

I already tried different ways to drive a webbrowser via Euphoria but I have never been able to get it work as I needed. WebDriver's wire protocol seems to be the way to go but I was not able to communicate correctly with either chromedriver or geckodriver because of missing information in headers or whatever else.

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

6. Re: Euphoria CGI

"whatever else" is mostly JSON data used in the requests.

new topic     » goto parent     » topic index » view message » categorize

7. Re: Euphoria CGI

I have been able to communicate with chromedriver via libcurl and following code (needs Eu3 Standard Library or Eu4 Standard Library or my libcurl wrapper):

include std/filesys.e 
include std/error.e 
include lib/_curl_constants_.e 
include lib/_curl_.e 
include std/console.e 
 
object res 
atom curl 
 
crash_file(InitialDir & SLASH & "ex.err") 
res = curl_global_init(CURL_GLOBAL_DEFAULT) 
curl = curl_easy_init() 
if curl then 
    curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP) 
    curl_easy_setopt(curl, CURLOPT_PROXY, "") 
    curl_easy_setopt(curl, CURLOPT_COOKIEFILE, InitialDir & SLASH & "cookies.txt") 
    curl_easy_setopt(curl, CURLOPT_COOKIEJAR, InitialDir & SLASH & "cookies.txt") 
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) 
    curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:9515/status") 
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1) 
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Connection: keep-alive") 
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Accept: application/json") 
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Content-Type: application/json; charset=UTF-8") 
 
    res = curl_easy_perform_ex(curl) 
 
    printf(1, "Status: %d\n", {res[1]}) 
    printf(1, "Effective URL: %s\n", {res[2]}) 
    analyze_object(res[3], "Headers", 1) 
    analyze_object(res[4], "Content", 1) 
 
  curl_easy_cleanup(curl) 
end if 
 
curl_global_cleanup() 
 
maybe_any_key() 

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

8. Re: Euphoria CGI

I have been able to communicate with chromedriver via libcurl and following code (needs Eu3 Standard Library or Eu4 Standard Library or my libcurl wrapper):

include std/filesys.e 
include std/error.e 
include lib/_debug_.e 
include lib/_curl_constants_.e 
include lib/_curl_.e 
include std/console.e 
 
object res 
atom curl 
 
crash_file(InitialDir & SLASH & "ex.err") 
res = curl_global_init(CURL_GLOBAL_DEFAULT) 
curl = curl_easy_init() 
if curl then 
    curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP) 
    curl_easy_setopt(curl, CURLOPT_PROXY, "") 
    curl_easy_setopt(curl, CURLOPT_COOKIEFILE, InitialDir & SLASH & "cookies.txt") 
    curl_easy_setopt(curl, CURLOPT_COOKIEJAR, InitialDir & SLASH & "cookies.txt") 
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) 
    curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:9515/status") 
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1) 
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Connection: keep-alive") 
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Accept: application/json") 
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Content-Type: application/json; charset=UTF-8") 
 
    res = curl_easy_perform_ex(curl) 
 
    printf(1, "Status: %d\n", {res[1]}) 
    printf(1, "Effective URL: %s\n", {res[2]}) 
    analyze_object(res[3], "Headers", 1) 
    analyze_object(res[4], "Content", 1) 
 
  curl_easy_cleanup(curl) 
end if 
 
curl_global_cleanup() 
 
maybe_any_key() 

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

9. Re: Euphoria CGI

I got it work with WinHTTP also

include std/dll.e 
include std/machine.e 
include std/math.e 
include std/filesys.e 
include std/console.e 
include lib/_conv_.e 
include lib/_debug_.e 
include lib/_w32errors_.e 
include lib/_winhttp_constants_.e 
include lib/_winhttp_.e 
 
atom hSession, hConnect, hRequest 
hSession = NULL 
hConnect = NULL 
hRequest = NULL 
 
procedure free_pointers() 
  integer bResults 
 
  if hRequest != NULL then bResults = WinHttpCloseHandle(hRequest) end if 
  if hConnect != NULL then bResults = WinHttpCloseHandle(hConnect) end if 
  if hSession != NULL then bResults = WinHttpCloseHandle(hSession) end if 
end procedure 
 
object Buffer 
integer bResults, dwSize, status 
sequence UserAgent, cookies, url, headers, content 
atom addr 
 
f_debug = open(InitialDir & SLASH & "debug.log", "w") 
 
Buffer = "" 
bResults = FALSE 
UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" 
 
-- Use WinHttpOpen to obtain a session handle. 
hSession = WinHttpOpen( UserAgent, 
                        WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 
                        WINHTTP_NO_PROXY_NAME, 
                        WINHTTP_NO_PROXY_BYPASS, 0) 
if hSession = NULL then 
  printf(1, "Error %d: %s\n", {error_code, error_msg}) 
  abort(1) 
end if 
printf(1, "hSession = %d\n", {hSession}) 
 
-- Specify an HTTP server. 
-- WinHTTP is Unicode only 
hConnect = WinHttpConnect( hSession, "127.0.0.1", 9515) 
if hConnect = NULL then 
  printf(1, "Error %d: %s\n", {error_code, error_msg}) 
  abort(1) 
end if 
printf(1, "hConnect = %d\n", {hConnect}) 
 
-- Create an HTTP request handle. 
  hRequest = WinHttpOpenRequest( hConnect, "GET", "/status", 
                                 NULL, WINHTTP_NO_REFERER, 
                                 {WINHTTP_DEFAULT_ACCEPT_TYPES}, 
                                 NULL) 
if hRequest = NULL then 
  printf(1, "Error %d: %s\n", {error_code, error_msg}) 
  abort(1) 
end if 
printf(1, "hRequest = %d\n", {hRequest}) 
 
-- Send a request. 
bResults = WinHttpSendRequest( hRequest, 
                               "Accept: application/json\r\nContent-Type: application/json; charset=UTF-8\r\n", 
                               NULL, 
                               0) 
if bResults = NULL then 
  printf(1, "Error %d: %s\n", {error_code, error_msg}) 
  abort(1) 
end if 
printf(1, "bResults = %d\n", {bResults}) 
 
-- End the request. 
bResults = WinHttpReceiveResponse( hRequest, NULL) 
if bResults = NULL then 
  printf(1, "Error %d: %s\n", {error_code, error_msg}) 
  abort(1) 
end if 
printf(1, "bResults = %d\n", {bResults}) 
 
-- Retrieve the header. 
Buffer = WinHttpQueryHeaders( hRequest ) 
-- Print the header contents. 
if sequence(Buffer) then 
  printf(1, "Header contents: \n%s", {Buffer}) 
  cookies = WinHttpExtractCookies(Buffer, 1) 
  analyze_object(cookies, "cookies") 
  cookies = WinHttpExtractCookies(Buffer) 
  analyze_object(cookies, "cookies") 
end if 
 
-- Retrieve page content. 
Buffer = "" 
dwSize = WinHttpQueryDataAvailable(hRequest) 
while dwSize do 
  Buffer &= WinHttpReadData(hRequest, dwSize) 
  dwSize = WinHttpQueryDataAvailable(hRequest) 
end while 
puts(1, Buffer & "\n") 
 
-- Close any open handles. 
free_pointers() 
close(f_debug) 
 
maybe_any_key() 
new topic     » goto parent     » topic index » view message » categorize

10. Re: Euphoria CGI

I am now able to drive Chrome through chromedriver via libcurl (not via WinHTTP, I don't know why). Here is an example of code:

include std/filesys.e 
include std/error.e 
include lib/_debug_.e 
include lib/_curl_constants_.e 
include lib/_curl_.e 
include lib/_json_.e 
include std/console.e 
 
object res 
atom curl 
 
f_debug = open(InitialDir & SLASH & "debug.log", "w") 
crash_file(InitialDir & SLASH & "ex.err") 
res = curl_global_init(CURL_GLOBAL_DEFAULT) 
curl = curl_easy_init() 
if curl then 
  curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP) 
  curl_easy_setopt(curl, CURLOPT_PROXY, "") 
  curl_easy_setopt(curl, CURLOPT_COOKIEFILE, InitialDir & SLASH & "cookies.txt") 
  curl_easy_setopt(curl, CURLOPT_COOKIEJAR, InitialDir & SLASH & "cookies.txt") 
  curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) 
  curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:9515/session") 
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1) 
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Connection: keep-alive") 
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Accept: application/json") 
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Content-Type: application/json; charset=UTF-8") 
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"desiredCapabilities\": {}}") 
--    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, length(postthis)) 
 
  res = curl_easy_perform_ex(curl) 
 
  printf(1, "Status: %d\n", {res[1]}) 
  printf(1, "Effective URL: %s\n", {res[2]}) 
  analyze_object(res[3], "Headers", 1) 
  analyze_object(res[4], "Content", 1) 
 
  sequence sessionId = get_json_value("sessionId", json_to_sequence(res[4]), 0) 
  printf(1, "Session ID: %s\n", {sessionId}) 
 
  curl_easy_reset(curl) 
   
  curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP) 
  curl_easy_setopt(curl, CURLOPT_PROXY, "") 
  curl_easy_setopt(curl, CURLOPT_COOKIEFILE, InitialDir & SLASH & "cookies.txt") 
  curl_easy_setopt(curl, CURLOPT_COOKIEJAR, InitialDir & SLASH & "cookies.txt") 
  curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) 
  curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:9515/session/" & sessionId & "/url") 
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1) 
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Connection: keep-alive") 
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Accept: application/json") 
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Content-Type: application/json; charset=UTF-8") 
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"url\": \"http://192.168.1.251:5000\"}") 
 
  res = curl_easy_perform_ex(curl) 
 
  printf(1, "Status: %d\n", {res[1]}) 
  printf(1, "Effective URL: %s\n", {res[2]}) 
  analyze_object(res[3], "Headers", 1) 
  analyze_object(res[4], "Content", 1) 
 
  curl_easy_cleanup(curl) 
end if 
 
curl_global_cleanup() 
 
close(f_debug) 
 
maybe_any_key() 

Next step is to improve the libcurl wrapper and to get a first demo working.

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

11. Re: Euphoria CGI

What about using HTML5 server-sent events? https://duckduckgo.com/?q=html5+server+events&ia=web

new topic     » goto parent     » topic index » view message » categorize

12. Re: Euphoria CGI

acEduardo said...

What about using HTML5 server-sent events? https://duckduckgo.com/?q=html5+server+events&ia=web

Maybe it's what you're thinking of: I intended to use Javascript to fire events (sending home-made UDP event frames to client side) as described here: https://www.w3schools.com/tags/ev_onmouseup.asp

It looks to me that HTML5 events are equivalent but I don't know how to handle them on client side. I need events to be catched by the OEU client that drives the browser, not by the browser itself.

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu