1. http_get.e

With Pete's permission I have endeavored to excerpt his http_get code from WEE 0.52's updater.ex into a stand alone include file, http_get.e.. Pete gave me some pointers and the code seems to work well under LINUX. I left Pete's Windows routine untouched. I hope I haven't mucked up Pete's code too much. Suggestions and ideas for improvement are welcome.

Thanks again, Pete!
Regards,
Ken Rhodes

-- 
--  https_get.e  
-- 
--  code extracted and modifed from Pete Eberleins WEE .52 updater.ex: 
--  Copyright (c) 1998-2018  Pete Eberlein 
--  
-- Permission is hereby granted, free of charge, to any person obtaining a copy 
-- of this software and associated documentation files (the "Software"), to deal 
-- in the Software without restriction, including without limitation the rights 
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
-- copies of the Software, and to permit persons to whom the Software is 
-- furnished to do so, subject to the following conditions: 
--  
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software. 
--  
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
-- THE SOFTWARE. 
 
--  minor LINUX modifications by Kenneth Rhodes: 
-------------------------------------------------------------------------------------------------------- 
--  supplementary routines: 
--  extract_fn(sequence url) 
--  write_file_data(sequence url) 
 
include std/console.e 
--include std/net/http.e  -- doesn't support https 
include std/io.e 
include std/get.e 
include std/filesys.e 
include std/hash.e 
include std/dll.e 
include std/machine.e 
include std/sequence.e 
 
 
ifdef WINDOWS then 
-- 
-- Implement http_get via WinINet for Windows 
-- 
 
constant 
    wininet = open_dll("wininet.dll") 
if wininet = 0 then 
    puts(1, "Failed to open wininet.dll\n") 
    abort(1) 
end if 
 
constant 
    InternetOpen = define_c_func(wininet, "InternetOpenA", {C_POINTER, C_DWORD, C_POINTER, C_POINTER, C_DWORD}, C_HANDLE), 
    InternetCloseHandle = define_c_func(wininet, "InternetCloseHandle", {C_HANDLE}, C_BOOL), 
    InternetOpenUrl = define_c_func(wininet, "InternetOpenUrlA", {C_HANDLE, C_POINTER, C_POINTER, C_DWORD, C_DWORD, C_POINTER}, C_HANDLE), 
    InternetReadFile = define_c_func(wininet, "InternetReadFile", {C_HANDLE, C_POINTER, C_DWORD, C_POINTER}, C_BOOL) 
if InternetOpen = -1 or 
   InternetCloseHandle = -1 or 
   InternetOpenUrl = -1 or 
   InternetReadFile = -1 then 
    puts(1, "Failed to find functions in wininet\n") 
    abort(1) 
end if 
 
constant 
    INTERNET_OPEN_TYPE_PRECONFIG = 0 
 
public function https_get(sequence url) 
    atom agent_ptr = allocate_string("Mozilla/4.0 (compatible)") 
    atom url_ptr = allocate_string(url) 
    atom ih, ch -- internet handle, connection handle 
    integer bufsize = 4096 
    atom buf_ptr = allocate(bufsize) 
    atom bytesread_ptr = allocate(4) -- LPDWORD 
    object res = -1 
 
    ih = c_func(InternetOpen, {agent_ptr, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0}) 
    if ih then 
        ch = c_func(InternetOpenUrl, {ih, url_ptr, NULL, 0, 0, NULL}) 
        if ch then 
            res = "" 
            while c_func(InternetReadFile, {ch, buf_ptr, bufsize, bytesread_ptr}) != 1 or 
                  peek4u(bytesread_ptr) != 0 do 
                res &= peek({buf_ptr, peek4u(bytesread_ptr)}) 
            end while 
--            res = {{{"Status","200"}}, res} 
            c_func(InternetCloseHandle, {ih}) 
        end if 
        c_func(InternetCloseHandle, {ih}) 
    end if 
 
    free(agent_ptr) 
    free(url_ptr) 
    free(buf_ptr) 
    free(bytesread_ptr) 
 
    return res 
end function 
 
elsedef 
 
-- 
-- Implement https_get via libcurl for UNIX 
-- 
 
integer libcurl = open_dll("libcurl.so") 
if libcurl = 0 then libcurl = open_dll("libcurl.so.3") end if 
if libcurl = 0 then libcurl = open_dll("libcurl.so.4") end if 
if libcurl = 0 then  puts(1, "Failed to open libcurl.so\n")  abort(1) end if 
 
constant 
    CURLOPT_URL = 10002, 
    CURLOPT_WRITEFUNCTION = 20011, 
    CURLOPT_WRITEDATA = 10001, 
    CURLOPT_FOLLOWLOCATION = 52 
 
sequence cb_data 
function curl_callback(atom ptr, atom size, atom nmemb, atom writedata) 
    cb_data &= peek({ptr, size * nmemb}) 
    return nmemb 
end function 
constant curl_cb = call_back(routine_id("curl_callback")) 
 
public function https_get(sequence url) 
atom url_ptr = allocate_string(url), res, curl 
integer curl_easy_init = define_c_func(libcurl, "curl_easy_init", {}, C_POINTER), 
    curl_easy_setopt =   define_c_proc(libcurl, "curl_easy_setopt", {C_POINTER, C_LONG, C_POINTER}), 
    curl_easy_perform =define_c_func(libcurl, "curl_easy_perform", {C_POINTER}, C_LONG), 
    curl_easy_cleanup =define_c_proc(libcurl, "curl_easy_cleanup", {C_POINTER}) 
    curl = c_func(curl_easy_init, {}) 
    if not curl then  
        fail("\nFailed to init libcurl\n")  
    return -1  
    end if 
    if not url_ptr or 
        curl_easy_init = -1 or    
        curl_easy_setopt = -1 or 
        curl_easy_perform = -1 or    
        curl_easy_cleanup = -1 then 
        fail("\nFailed to find functions in libcurl\n") 
    return -1  
    end if 
    c_proc(curl_easy_setopt, {curl, CURLOPT_WRITEFUNCTION, curl_cb}) 
    c_proc(curl_easy_setopt, {curl, CURLOPT_WRITEDATA, 0}) 
    c_proc(curl_easy_setopt, {curl, CURLOPT_FOLLOWLOCATION, 1}) 
    cb_data = "" 
    c_proc(curl_easy_setopt, {curl, CURLOPT_URL, url_ptr}) 
    res = c_func(curl_easy_perform, {curl}) 
    free(url_ptr)     
    c_proc(curl_easy_cleanup, {curl})  
    if res = 0 then  
         if match("Error", sprintf("%s",{cb_data})) or 
         match("404 Not Found", sprintf("%s",{cb_data}))then 
            fail(cb_data) 
        else 
            return cb_data  
        end if 
    end if 
return -1 
end function 
 
end ifdef  
 
public function extract_fn(sequence url) 
-- extract a file name from a url 
integer z = length(url) 
sequence fn="" 
    for i = z  to 1 by -1  do 
        if equal({SLASH}, sprintf("%s",url[i])) then  
            fn = slice(url, i+1, z) 
            exit  
        end if 
    end for 
return fn 
end function 
 
function fail(sequence msg) 
sequence txt = "\n\nPress any key to exit\n" 
    display(msg & txt) 
    wait_key() 
return 0 
end function 
 
public function write_file_data(sequence url)  
-- returns 1 if write_file_data succeeds  
-- returns 0 otherwise 
integer exit_code = 1 
object data 
sequence fn = extract_fn(url) 
     if length(fn) then  
        data = https_get(url)  
        if atom(data) then 
            exit_code = fail(sprintf("\nFailed to download file: %s\n", {fn})) 
        else 
            if write_file(fn,data) = -1 then 
               exit_code = fail(sprintf("\nFailed to write_file %s\n", {fn}))  
            else  
                display(sprintf("\nwrite_file_data %s successfull\n", {fn}))  
            end if 
        end if 
    else  
       exit_code = fail(sprintf("\nFailed to extract a file name from: %s", {url})) 
    end if 
return exit_code 
end function 
 
-- test 
-- constant archive = "https://archive.usingeuphoria.com/" 
-- write_file_data(archive & "euhelp.tar")  
-- displays error message: file not downloaded 
-- write_file_data(archive & "euhelper.tar") 
-- write_file_data(archive & "simple.tar") 
 
 
 
new topic     » topic index » view message » categorize

2. Re: http_get.e -- LINUX CODE

- 
--  https_get.e  
-- 
--  code extracted and modifed from Pete Eberleins WEE .52 updater.ex: 
--  Copyright (c) 1998-2018  Pete Eberlein 
--  
-- Permission is hereby granted, free of charge, to any person obtaining a copy 
-- of this software and associated documentation files (the "Software"), to deal 
-- in the Software without restriction, including without limitation the rights 
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
-- copies of the Software, and to permit persons to whom the Software is 
-- furnished to do so, subject to the following conditions: 
--  
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software. 
--  
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
-- THE SOFTWARE. 
 
--  minor LINUX modifications by Kenneth Rhodes: 
-------------------------------------------------------------------------------------------------------- 
--  supplementary routines: 
--  extract_fn(sequence url) 
--  write_file_data(sequence url) 
 
include std/console.e 
--include std/net/http.e  -- doesn't support https 
include std/io.e 
include std/get.e 
include std/filesys.e 
include std/hash.e 
include std/dll.e 
include std/machine.e 
include std/sequence.e 
 
 
ifdef WINDOWS then 
-- 
-- Implement http_get via WinINet for Windows 
-- 
 
constant 
    wininet = open_dll("wininet.dll") 
if wininet = 0 then 
    puts(1, "Failed to open wininet.dll\n") 
    abort(1) 
end if 
 
constant 
    InternetOpen = define_c_func(wininet, "InternetOpenA", {C_POINTER, C_DWORD, C_POINTER, C_POINTER, C_DWORD}, C_HANDLE), 
    InternetCloseHandle = define_c_func(wininet, "InternetCloseHandle", {C_HANDLE}, C_BOOL), 
    InternetOpenUrl = define_c_func(wininet, "InternetOpenUrlA", {C_HANDLE, C_POINTER, C_POINTER, C_DWORD, C_DWORD, C_POINTER}, C_HANDLE), 
    InternetReadFile = define_c_func(wininet, "InternetReadFile", {C_HANDLE, C_POINTER, C_DWORD, C_POINTER}, C_BOOL) 
if InternetOpen = -1 or 
   InternetCloseHandle = -1 or 
   InternetOpenUrl = -1 or 
   InternetReadFile = -1 then 
    puts(1, "Failed to find functions in wininet\n") 
    abort(1) 
end if 
 
constant 
    INTERNET_OPEN_TYPE_PRECONFIG = 0 
 
public function https_get(sequence url) 
    atom agent_ptr = allocate_string("Mozilla/4.0 (compatible)") 
    atom url_ptr = allocate_string(url) 
    atom ih, ch -- internet handle, connection handle 
    integer bufsize = 4096 
    atom buf_ptr = allocate(bufsize) 
    atom bytesread_ptr = allocate(4) -- LPDWORD 
    object res = -1 
 
    ih = c_func(InternetOpen, {agent_ptr, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0}) 
    if ih then 
        ch = c_func(InternetOpenUrl, {ih, url_ptr, NULL, 0, 0, NULL}) 
        if ch then 
            res = "" 
            while c_func(InternetReadFile, {ch, buf_ptr, bufsize, bytesread_ptr}) != 1 or 
                  peek4u(bytesread_ptr) != 0 do 
                res &= peek({buf_ptr, peek4u(bytesread_ptr)}) 
            end while 
--            res = {{{"Status","200"}}, res} 
            c_func(InternetCloseHandle, {ih}) 
        end if 
        c_func(InternetCloseHandle, {ih}) 
    end if 
 
    free(agent_ptr) 
    free(url_ptr) 
    free(buf_ptr) 
    free(bytesread_ptr) 
 
    return res 
end function 
 
elsedef 
 
-- 
-- Implement https_get via libcurl for UNIX 
-- 
 
integer libcurl = open_dll("libcurl.so") 
if libcurl = 0 then libcurl = open_dll("libcurl.so.3") end if 
if libcurl = 0 then libcurl = open_dll("libcurl.so.4") end if 
if libcurl = 0 then  puts(1, "Failed to open libcurl.so\n")  abort(1) end if 
 
constant 
    CURLOPT_URL = 10002, 
    CURLOPT_WRITEFUNCTION = 20011, 
    CURLOPT_WRITEDATA = 10001, 
    CURLOPT_FOLLOWLOCATION = 52 
 
sequence cb_data 
function curl_callback(atom ptr, atom size, atom nmemb, atom writedata) 
    cb_data &= peek({ptr, size * nmemb}) 
    return nmemb 
end function 
constant curl_cb = call_back(routine_id("curl_callback")) 
 
public function https_get(sequence url) 
atom url_ptr = allocate_string(url), res, curl 
integer curl_easy_init = define_c_func(libcurl, "curl_easy_init", {}, C_POINTER), 
    curl_easy_setopt =   define_c_proc(libcurl, "curl_easy_setopt", {C_POINTER, C_LONG, C_POINTER}), 
    curl_easy_perform =define_c_func(libcurl, "curl_easy_perform", {C_POINTER}, C_LONG), 
    curl_easy_cleanup =define_c_proc(libcurl, "curl_easy_cleanup", {C_POINTER}) 
    curl = c_func(curl_easy_init, {}) 
    if not curl then  
        fail("\nFailed to init libcurl\n")  
    return -1  
    end if 
    if not url_ptr or 
        curl_easy_init = -1 or    
        curl_easy_setopt = -1 or 
        curl_easy_perform = -1 or    
        curl_easy_cleanup = -1 then 
        fail("\nFailed to find functions in libcurl\n") 
    return -1  
    end if 
    c_proc(curl_easy_setopt, {curl, CURLOPT_WRITEFUNCTION, curl_cb}) 
    c_proc(curl_easy_setopt, {curl, CURLOPT_WRITEDATA, 0}) 
    c_proc(curl_easy_setopt, {curl, CURLOPT_FOLLOWLOCATION, 1}) 
    cb_data = "" 
    c_proc(curl_easy_setopt, {curl, CURLOPT_URL, url_ptr}) 
    res = c_func(curl_easy_perform, {curl}) 
    free(url_ptr)     
    c_proc(curl_easy_cleanup, {curl})  
    if res = 0 then  
         if match("Error", sprintf("%s",{cb_data})) or 
         match("404 Not Found", sprintf("%s",{cb_data}))then 
            fail(cb_data) 
        else 
            return cb_data  
        end if 
    end if 
return -1 
end function 
 
end ifdef  
 
public function extract_fn(sequence url) 
-- extract a file name from a url 
integer z = length(url) 
sequence fn="" 
    for i = z  to 1 by -1  do 
        if equal({SLASH}, sprintf("%s",url[i])) then  
            fn = slice(url, i+1, z) 
            exit  
        end if 
    end for 
return fn 
end function 
 
function fail(sequence msg) 
sequence txt = "\n\nPress any key to exit\n" 
    display(msg & txt) 
    wait_key() 
return 0 
end function 
 
public function write_file_data(sequence url)  
-- returns 1 if write_file_data succeeds  
-- returns 0 otherwise 
integer exit_code = 1 
object data 
sequence fn = extract_fn(url) 
     if length(fn) then  
        data = https_get(url)  
        if atom(data) then 
            exit_code = fail(sprintf("\nFailed to download file: %s\n", {fn})) 
        else 
            if write_file(fn,data) = -1 then 
               exit_code = fail(sprintf("\nFailed to write_file %s\n", {fn}))  
            else  
                display(sprintf("\nwrite_file_data %s successfull\n", {fn}))  
            end if 
        end if 
    else  
       exit_code = fail(sprintf("\nFailed to extract a file name from: %s", {url})) 
    end if 
return exit_code 
end function 
 
-- test 
-- constant archive = "https://archive.usingeuphoria.com/" 
-- write_file_data(archive & "euhelp.tar")  
-- displays error message: file not downloaded 
-- write_file_data(archive & "euhelper.tar") 
-- write_file_data(archive & "simple.tar") 
new topic     » goto parent     » topic index » view message » categorize

3. Re: http_get.e -- LINUX CODE

Some might wonder why not use std/net/http.e? The std/net/http.e is rather useless and it is a good idea to use a CURL library for this. The standard library routines uses HTTP only and the world has upgraded to HTTPS. You could adapt the included Euphoria unit tests for this code. Also, it wouldn't be such a bad idea to adopt this for std/net/http.

S D Pringle

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

4. Re: http_get.e -- LINUX CODE

SDPringle said...

Also, it wouldn't be such a bad idea to adopt this for std/net/http.

I think it'd be a great idea to integrate this into std/net/http. We can use curl on Linux/OSX and WinInet on Windows.

By the way, I've had a complete WinInet wrapper written for a while now: https://github.com/ghaberek/WinInet/. cklester has been using it in his projects.

You can use HttpGetRequest() as a drop-in replacement for http_get(). I can add in HttpPostRequest() if someone's going to be using it.

-Greg

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

5. Re: https_get.e

I got carried away thinking maybe the file and functions should be called "https_get". Also, I changed the procedures to functions thinking that perhaps an include file should not call abort().

https_get(url) now catches and displays "404 Not Found" found error without writing a "dead" file. Commented out the Windows line specific to "updater.ex" usage.

-- 
--  https_get.e  
-- 
--  code extracted and modifed from Pete Eberleins WEE .52 updater.ex: 
--  Copyright (c) 1998-2018  Pete Eberlein 
--  
-- Permission is hereby granted, free of charge, to any person obtaining a copy 
-- of this software and associated documentation files (the "Software"), to deal 
-- in the Software without restriction, including without limitation the rights 
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
-- copies of the Software, and to permit persons to whom the Software is 
-- furnished to do so, subject to the following conditions: 
--  
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software. 
--  
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
-- THE SOFTWARE. 
 
--  minor LINUX modifications by Kenneth Rhodes: 
-------------------------------------------------------------------------------------------------------- 
--  supplementary routines: 
--  extract_fn(sequence url) 
--  write_file_data(sequence url) 
 
include std/console.e 
--include std/net/http.e  -- doesn't support https 
include std/io.e 
include std/get.e 
include std/filesys.e 
include std/hash.e 
include std/dll.e 
include std/machine.e 
include std/sequence.e 
 
 
ifdef WINDOWS then 
-- 
-- Implement http_get via WinINet for Windows 
-- 
 
constant 
    wininet = open_dll("wininet.dll") 
if wininet = 0 then 
    puts(1, "Failed to open wininet.dll\n") 
    abort(1) 
end if 
 
constant 
    InternetOpen = define_c_func(wininet, "InternetOpenA", {C_POINTER, C_DWORD, C_POINTER, C_POINTER, C_DWORD}, C_HANDLE), 
    InternetCloseHandle = define_c_func(wininet, "InternetCloseHandle", {C_HANDLE}, C_BOOL), 
    InternetOpenUrl = define_c_func(wininet, "InternetOpenUrlA", {C_HANDLE, C_POINTER, C_POINTER, C_DWORD, C_DWORD, C_POINTER}, C_HANDLE), 
    InternetReadFile = define_c_func(wininet, "InternetReadFile", {C_HANDLE, C_POINTER, C_DWORD, C_POINTER}, C_BOOL) 
if InternetOpen = -1 or 
   InternetCloseHandle = -1 or 
   InternetOpenUrl = -1 or 
   InternetReadFile = -1 then 
    puts(1, "Failed to find functions in wininet\n") 
    abort(1) 
end if 
 
constant 
    INTERNET_OPEN_TYPE_PRECONFIG = 0 
 
public function https_get(sequence url) 
    atom agent_ptr = allocate_string("Mozilla/4.0 (compatible)") 
    atom url_ptr = allocate_string(url) 
    atom ih, ch -- internet handle, connection handle 
    integer bufsize = 4096 
    atom buf_ptr = allocate(bufsize) 
    atom bytesread_ptr = allocate(4) -- LPDWORD 
    object res = -1 
 
    ih = c_func(InternetOpen, {agent_ptr, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0}) 
    if ih then 
        ch = c_func(InternetOpenUrl, {ih, url_ptr, NULL, 0, 0, NULL}) 
        if ch then 
            res = "" 
            while c_func(InternetReadFile, {ch, buf_ptr, bufsize, bytesread_ptr}) != 1 or 
                  peek4u(bytesread_ptr) != 0 do 
                res &= peek({buf_ptr, peek4u(bytesread_ptr)}) 
            end while 
--            res = {{{"Status","200"}}, res} 
            c_func(InternetCloseHandle, {ih}) 
        end if 
        c_func(InternetCloseHandle, {ih}) 
    end if 
 
    free(agent_ptr) 
    free(url_ptr) 
    free(buf_ptr) 
    free(bytesread_ptr) 
 
    return res 
end function 
 
elsedef 
 
-- 
-- Implement https_get via libcurl for UNIX 
-- 
 
integer libcurl = open_dll("libcurl.so") 
if libcurl = 0 then libcurl = open_dll("libcurl.so.3") end if 
if libcurl = 0 then libcurl = open_dll("libcurl.so.4") end if 
if libcurl = 0 then  puts(1, "Failed to open libcurl.so\n")  abort(1) end if 
 
constant 
    CURLOPT_URL = 10002, 
    CURLOPT_WRITEFUNCTION = 20011, 
    CURLOPT_WRITEDATA = 10001, 
    CURLOPT_FOLLOWLOCATION = 52 
 
sequence cb_data 
function curl_callback(atom ptr, atom size, atom nmemb, atom writedata) 
    cb_data &= peek({ptr, size * nmemb}) 
    return nmemb 
end function 
constant curl_cb = call_back(routine_id("curl_callback")) 
 
public function https_get(sequence url) 
atom url_ptr = allocate_string(url), res, curl 
integer curl_easy_init = define_c_func(libcurl, "curl_easy_init", {}, C_POINTER), 
    curl_easy_setopt =   define_c_proc(libcurl, "curl_easy_setopt", {C_POINTER, C_LONG, C_POINTER}), 
    curl_easy_perform =define_c_func(libcurl, "curl_easy_perform", {C_POINTER}, C_LONG), 
    curl_easy_cleanup =define_c_proc(libcurl, "curl_easy_cleanup", {C_POINTER}) 
    curl = c_func(curl_easy_init, {}) 
    if not curl then  
        fail("\nFailed to init libcurl\n")  
    return -1  
    end if 
    if not url_ptr or 
        curl_easy_init = -1 or    
        curl_easy_setopt = -1 or 
        curl_easy_perform = -1 or    
        curl_easy_cleanup = -1 then 
        fail("\nFailed to find functions in libcurl\n") 
    return -1  
    end if 
    c_proc(curl_easy_setopt, {curl, CURLOPT_WRITEFUNCTION, curl_cb}) 
    c_proc(curl_easy_setopt, {curl, CURLOPT_WRITEDATA, 0}) 
    c_proc(curl_easy_setopt, {curl, CURLOPT_FOLLOWLOCATION, 1}) 
    cb_data = "" 
    c_proc(curl_easy_setopt, {curl, CURLOPT_URL, url_ptr}) 
    res = c_func(curl_easy_perform, {curl}) 
    free(url_ptr)     
    c_proc(curl_easy_cleanup, {curl})  
    if res = 0 then  
         if match("Error", sprintf("%s",{cb_data})) or 
         match("404 Not Found", sprintf("%s",{cb_data}))then 
            fail(cb_data) 
        else 
            return cb_data  
        end if 
    end if 
return -1 
end function 
 
end ifdef  
 
public function extract_fn(sequence url) 
-- extract a file name from a url 
integer z = length(url) 
sequence fn="" 
    for i = z  to 1 by -1  do 
        if equal({SLASH}, sprintf("%s",url[i])) then  
            fn = slice(url, i+1, z) 
            exit  
        end if 
    end for 
return fn 
end function 
 
function fail(sequence msg) 
sequence txt = "\n\nPress any key to exit\n" 
    display(msg & txt) 
    wait_key() 
return 0 
end function 
 
public function write_file_data(sequence url)  
-- returns 1 if write_file_data succeeds  
-- returns 0 otherwise 
integer exit_code = 1 
object data 
sequence fn = extract_fn(url) 
     if length(fn) then  
        data = https_get(url)  
        if atom(data) then 
            exit_code = fail(sprintf("\nFailed to download file: %s\n", {fn})) 
        else 
            if write_file(fn,data) = -1 then 
               exit_code = fail(sprintf("\nFailed to write_file %s\n", {fn}))  
            else  
                display(sprintf("\nwrite_file_data %s successfull\n", {fn}))  
            end if 
        end if 
    else  
       exit_code = fail(sprintf("\nFailed to extract a file name from: %s", {url})) 
    end if 
return exit_code 
end function 
 
-- test 
-- constant archive = "https://archive.usingeuphoria.com/" 
-- write_file_data(archive & "euhelp.tar")  
-- displays error message: file not downloaded 
-- write_file_data(archive & "euhelper.tar") 
-- write_file_data(archive & "simple.tar") 
 
new topic     » goto parent     » topic index » view message » categorize

6. Re: https_get.e

I have removed all dependencies to other EU4 Standard libraries of my libcurl4 library. It is available here with a demo file :

http://jean-marc.duro.pagesperso-orange.fr/libcurl4.zip

Jean-Marc

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

7. Re: https_get.e

I bet you guys could create a https_post too, eh?

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

8. Re: https_get.e

SDPringle said...

I bet you guys could create a https_post too, eh?

Will this work from JMDuro's libcurl4.e - curl_demo.ex:

 
-- from:libcurl4.e 
----------------------------------------------------------------- 
public function curl_post(atom curl, sequence url, sequence headers, 
                          object body) 
--<function> 
--<name>curl_post</name> 
--<digest>sends a POST request to an URL and gets the page</digest> 
--<desc> 
-- intended to be used with REST APIs 
--</desc> 
--<param> 
--<type>atom</type> 
--<name>handle</name> 
--<desc>CURL session handle</desc> 
--</param> 
--<param> 
--<type>sequence</type> 
--<name>url</name> 
--<desc>URL to get the page from</desc> 
--</param> 
--<param> 
--<type>sequence</type> 
--<name>headers</name> 
--<desc>list of request headers</desc> 
--</param> 
--<param> 
--<type>object</type> 
--<name>body</name> 
--<desc>body of the request. Either a string or NULL.</desc> 
--</param> 
--<return> 
-- sequence 
-- * status  : HTTP status 
-- * url     : effective URL (useful if redirection is followed) 
-- * headers : sequence of headers 
-- * content : HTML Page content 
--</return> 
--<example> 
-- constant DEFAULT_HEADERS = { 
--   "Host: 192.168.1.10", 
--   "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0 " & 
--     "Gecko/20100101 Firefox/45.0", 
--   "Accept: application/json" 
-- } 
-- 
-- object res = curl_post(curl, MY_REST_API & "/session/" & sessionId & 
--                        "/timeouts/implicit_wait", DEFAULT_HEADERS, "{" & 
--                   "\"sessionId\": \"" & sessionId & "\", " & 
--                   sprintf("\"ms\": %d", ms) & 
--                 "}") 
-- printf(1, "Status: %d\n", {res[1]}) 
-- printf(1, "Effective URL: %s\n", {res[2]}) 
-- analyze_object(res[3], "Headers", {{"output", 2}}) 
-- analyze_object(res[4], "Content", {{"output", 2}}) 
--</example> 
--<see_also>curl_easy_perform, curl_easy_perform_ex, curl_get, curl_put, curl_delete, curl_patch, curl_head</see_also> 
--</function> 
  sequence res 
  atom pheaders 
 
  curl_easy_setopt(curl, CURLOPT_URL, url) 
  pheaders = NULL 
  for i = 1 to length(headers) do 
    pheaders = curl_slist_append(pheaders, headers[i]) 
  end for 
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, pheaders) 
  curl_easy_setopt(curl, CURLOPT_POST, 1) 
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body) 
 
  res = curl_easy_perform_ex(curl) 
  curl_slist_free_all(pheaders) 
  return res 
end function 
 
-------------------------------------------------------------------------------- 
 
-- from: curl_demo.ex 
-- 
-------------------------------------------------------------------------------- 
-- CURL POST - Beginner 
-------------------------------------------------------------------------------- 
res = curl_global_init(CURL_GLOBAL_DEFAULT) 
curl = init_curl_session() 
if curl then 
 
  res = curl_post(curl, "https://jsonplaceholder.typicode.com/posts", 
                  {"Content-type: application/json; charset=UTF-8"}, 
                  "{ \"title\": \"foo\", \"body\": \"bar\", \"userId\": 1 }") 
  if (res[HTTP_STATUS] < 200) or (res[HTTP_STATUS] > 226) then 
    puts(1, "POST failed!\n" & res[HTTP_BODY] & "\n") 
  end if 
  puts(1, "Result:\n" & res[HTTP_BODY] & "\n") 
 
  curl_easy_cleanup(curl) 
end if 
curl_global_cleanup() 
new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu