Using RingLibCurl

In this chapter we will learn about using RingLibCurl

Get Request

Example:

load "libcurl.ring"

curl = curl_easy_init()

curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.54.1")
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1)
curl_easy_setopt(curl, CURLOPT_URL, "https://ring-lang.github.io/")

curl_easy_perform(curl)

curl_easy_cleanup(curl)

Post Request

Example:

load "libcurl.ring"

curl = curl_easy_init()

curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.54.1")

cPostThis = "page=4&Number1=4&Number2=5"
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost/ringapp/index.ring?page=3")
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, cPostThis)

curl_easy_perform(curl)

curl_easy_cleanup(curl)

Facebook Login

Example:

load "libcurl.ring"

see "Enter Email : " give $login_email
See "Enter Password : " give $login_pass

curl = curl_easy_init()

curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.54.1")

curl_easy_setopt(curl, CURLOPT_URL, 'https://www.facebook.com/login.php')
curl_easy_setopt(curl, CURLOPT_POSTFIELDS,'charset_test=j u s t a t e s t'+
' &email='+urlencode($login_email)+'&pass='+
urlencode($login_pass)+'&login=Login')
curl_easy_setopt(curl, CURLOPT_POST, 1)
curl_easy_setopt(curl, CURLOPT_HEADER, 0)
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1)
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt")
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookies.txt")
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U;"+
" Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3")
curl_easy_setopt(curl, CURLOPT_REFERER, "http://www.facebook.com")
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE)
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2)

mylist = curl_slist_append(NULL,'Accept-Charset: utf-8')
curl_slist_append(mylist,'Accept-Language: en-us,en;q=0.7,bn-bd;q=0.3')
curl_slist_append(mylist,'Accept: text/xml,application/xml,'+
'application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5')
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, mylist)

curl_easy_setopt(curl, CURLOPT_COOKIESESSION, false)

curl_easy_perform(curl)

curl_easy_cleanup(curl)

Func URLEncode cStr
        cOut = ""
        for x in cStr
                if isalnum(x)
                        cOut += x
                but x = " "
                        cOut += "+"
                else
                        cOut += "%"+str2hex(x)
                ok
        next
        return cOut

Save Output to String

Example:

load "libcurl.ring"

curl = curl_easy_init()

curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.54.1")
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1)
curl_easy_setopt(curl, CURLOPT_URL, "https://ring-lang.github.io/")

cOutput = curl_easy_perform_silent(curl)

See "Output:" + nl
see cOutput

curl_easy_cleanup(curl)

Get Stock Data From Yahoo

Example:

Load "libcurl.ring"

### Part 1 --- Get Crumb and Cookie -----------------------------------------

See "Start curl_easy_init(): "+ nl
curl = curl_easy_init()                     ### >>> HANDLE >>> 01006BD0  CURL  0

        curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.54.1")
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1)
        curl_easy_setopt(curl, CURLOPT_COOKIEJAR,  "cookies.txt")
        curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookies.txt")
        curl_easy_setopt(curl, CURLOPT_URL, "https://finance.yahoo.com/quote/AMZN/history")

        ###  HTML Data >>> STDOUT Window,  Use curl_easy_perform_silent >>> String

cOutput = curl_easy_perform_silent(curl)    ### GO Get Data >>> String


###   Extract Crumb from data
###  "CrumbStore":{"crumb":"abcdefghijk"},

if cOutput != NULL

        newStr1     = substr(cOutput, substr(cOutput, '"CrumbStore":{"crumb":"' ), 48 )
                nPosS   = substr(newStr1, ':"' ) ;  ### Start of crumb -2
                nPosE   = substr(newStr1, '"}' ) ;  ### End   of crumb
                nCount  = nPosE - nPosS -2          ### size  of crumb
        myCrumb     = substr(newStr1, nPosS +2, nCount)

        See "myCrumb.: |"+ myCrumb +"|" +nl

        ### UniCode "\u002F" replace it with "/"
                if substr( myCrumb, "\u002F")
                   myCrumb = substr( myCrumb, "\u002F", "/")
                   See "myCrumb2: |"+ myCrumb +"|"+ nl
                ok

else
        See "No Connectivity to Yahoo. Looking for Cookie and Crumb." +nl +nl
ok


### Part 2 --- Send URL with Crumb, and Cookie -----------------------------------------

        ### Send URL+Crumb to Yahoo to fetch 1st stock history data,

        $url = "https://query1.finance.yahoo.com/v7/finance/download/AMZN"+
                "?period1=1277856000&period2=1498777545&interval=1wk" +
                "&events=history&crumb=" + myCrumb

        curl_easy_setopt(curl, CURLOPT_URL, $url);
        cStr = curl_easy_perform_silent(curl)
        See cStr

curl_easy_cleanup(curl)  ### REMEMBER to CLOSE  CURL

Output:

myCrumb.: |sEEeW97mxvN|
Date,Open,High,Low,Close,Adj Close,Volume
2010-07-05,110.650002,117.480003,109.000000,117.260002,117.260002,21000400
2010-07-12,117.809998,124.879997,117.320000,118.489998,118.489998,29407300
2010-07-19,118.379997,121.250000,105.800003,118.870003,118.870003,74252100

Helper Functions

RingLibCurl provides several helper functions to easily retrieve information about HTTP responses.

Get Response Information

Example:

load "libcurl.ring"

curl = curl_easy_init()

curl_easy_setopt_2(curl, CURLOPT_URL, "https://ring-lang.github.io/")
curl_easy_setopt_2(curl, CURLOPT_USERAGENT, "RingLibCurl")
curl_easy_setopt_1(curl, CURLOPT_FOLLOWLOCATION, 1)

curl_easy_perform_silent(curl)

? "Response Code: " + curl_getResponseCode(curl)
? "Content Type: " + curl_getContentType(curl)
? "Content Length: " + curl_getContentLength(curl)
? "Effective URL: " + curl_getEffectiveUrl(curl)
? "Redirect URL: " + curl_getRedirectUrl(curl)
? "Redirect Count: " + curl_getRedirectCount(curl)
? "Total Time: " + curl_getTotalTime(curl)
? "Name Lookup Time: " + curl_getNameLookupTime(curl)
? "Connect Time: " + curl_getConnectTime(curl)
? "Request Size: " + curl_getRequestSize(curl)
? "Header Size: " + curl_getHeaderSize(curl)
? "Speed Download: " + curl_getSpeedDownload(curl)
? "Speed Upload: " + curl_getSpeedUpload(curl)
? "SSL Verify Result: " + curl_getSSLVerifyResult(curl)
? "Primary IP: " + curl_getPrimaryIP(curl)
? "Primary Port: " + curl_getPrimaryPort(curl)
? "Local IP: " + curl_getLocalIP(curl)
? "Local Port: " + curl_getLocalPort(curl)
? "Content Length Upload: " + curl_getContentLengthUpload(curl)
? "Download Size: " + curl_getDownloadSize(curl)
? "Upload Size: " + curl_getUploadSize(curl)
? "File Time: " + curl_getFiletime(curl)
? "App Connect Time: " + curl_getAppConnectTime(curl)
? "Content Length Header: " + curl_getContentLengthHeader(curl)
? "Start Transfer Time: " + curl_getStartTransferTime(curl)
? "Pre Transfer Time: " + curl_getPreTransferTime(curl)

curl_easy_cleanup(curl)

Download and Check Status

Example:

load "libcurl.ring"

# Download a file from URL and save it to a local file
downloadFile("https://ring-lang.github.io/", "test_download.txt")

# Function to download file from URL and save to specified local path
func downloadFile URL, cFile
        # Initialize a new curl session
        curl = curl_easy_init()

        # Open file in binary write mode
        fp = fopen(cFile,"wb")

        # Set curl options:
        # Specify where to write the downloaded data
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp)
        # Set the URL to download from
        curl_easy_setopt(curl, CURLOPT_URL, URL)
        # Follow redirects if any
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1)

        # Perform the download
        curl_easy_perform(curl)

        # Get response information
        nResponseCode = curl_getResponseCode(curl)
        cContentType = curl_getContentType(curl)

        # Clean up: close file and curl session
        fclose(fp)
        curl_easy_cleanup(curl)

        # Check if download was successful (HTTP 200 OK)
        if nResponseCode = 200
                ? "File downloaded successfully!"
                return true
        else
                ? "Failed to download file."
                ? "HTTP Response Code: " + nResponseCode
                return false
        ok

Using Callbacks

RingLibCurl supports using callbacks for different operations like handling the response data, headers, progress information and reading data for upload.

We can set the callback function using curl_easy_setopt and the option name. The callback function can get the data using curl_get_data() or curl_get_progress_info().

Example (1): Using the Write Callback

load "libcurl.ring"

func main
        curl = curl_easy_init()
        curl_easy_setopt(curl, CURLOPT_URL, "https://ring-lang.github.io")
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, :write_callback)
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1)
        curl_easy_perform(curl)
        curl_easy_cleanup(curl)

func write_callback
        cData = curl_get_data()
        ? "Received Data Size: " + len(cData)

Example (2): Using the Progress Callback

load "libcurl.ring"

func main
        curl = curl_easy_init()
        curl_easy_setopt(curl, CURLOPT_URL, "https://ring-lang.github.io")
        curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, :progress_callback)
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1)
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0)
        curl_easy_perform(curl)
        curl_easy_cleanup(curl)

func progress_callback
        aInfo = curl_get_progress_info()
        dltotal = aInfo[1]
        dlnow = aInfo[2]
        ultotal = aInfo[3]
        ulnow = aInfo[4]
        ? "Progress: DL=" + dlnow + "/" + dltotal +
                " UL=" + ulnow + "/" + ultotal
        curl_set_progress_result(0)

Example (3): Using the Header Callback

load "libcurl.ring"

func main
        curl = curl_easy_init()
        curl_easy_setopt(curl, CURLOPT_URL, "https://ring-lang.github.io")
        curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, :header_callback)
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1)
        curl_easy_setopt(curl, CURLOPT_NOBODY, 1)
        curl_easy_perform(curl)
        curl_easy_cleanup(curl)

func header_callback
        cData = curl_get_data()
        ? "Header: " + trim(cData)

Example (4): Using the Read Callback

load "libcurl.ring"

uploadData = "This is test data from RingLibCurl"
uploadPos = 0

func main
        curl = curl_easy_init()
        curl_easy_setopt(curl, CURLOPT_URL, "https://postman-echo.com/put")
        curl_easy_setopt(curl, CURLOPT_UPLOAD, 1)
        curl_easy_setopt(curl, CURLOPT_READFUNCTION, :read_callback)
        curl_easy_setopt(curl, CURLOPT_INFILESIZE, len(uploadData))
        curl_easy_perform(curl)
        curl_easy_cleanup(curl)

func read_callback
        remaining = len(uploadData) - uploadPos
        if remaining > 0
                chunkSize = 16
                if remaining < chunkSize chunkSize = remaining ok
                chunk = substr(uploadData, uploadPos + 1, chunkSize)
                uploadPos += chunkSize
                curl_set_read_data(chunk)
        else
                curl_set_read_data("")
        ok