1. Post #1
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    gm_curly is a multi threaded, object orientated, callback based CURL implementation.

    It supports in its current form, HTTP, HTTPS and FTP(Get Only)


    Magic Definitions

    Errors(Not defined in Lua) - http://curl.haxx.se/libcurl/c/libcurl-errors.html
    Options(Defined in Lua) - http://curl.haxx.se/libcurl/c/curl_easy_setopt.html




    Functions

    -- Takes 0:
    --     
    -- Returns 1:
    --     Curly Object
    -- Callback none
    Curly( )
    
    -- Takes 1:
    --     function( CurlyOBJ, errorCode, data )
    -- Returns 0:
    --     
    -- Callback none
    Curly:SetCallback( function )
    
    -- Takes 1:
    --     bool - false means the data parameter in the callback will always be a string.
    --          - true means the data parameter in the callback will be a BinRead object.
    -- Returns 0:
    --     
    -- Callback none
    Curly:SetBinaryMode( bool )
    
    -- Takes 1:
    --     Url String
    -- Returns 1:
    --     Error Code - 0 means OK
    -- Callback none
    Curly:SetUrl( url )
    
    -- Takes 0:
    --     
    -- Returns 1:
    --     Error Code - 0 means OK
    -- Callback is called when completed.
    Curly:Perform( )
    
    -- Takes 1:
    --     Cookie String - "name1=content1; name2=content2;" etc.
    -- Returns 1:
    --     Error Code - 0 means OK
    -- Callback none
    Curly:SetCookies( cookies )
    
    -- Takes 2:
    --     CURLOPT_*
    --     integer value
    -- Returns 1:
    --     Error Code - 0 means OK
    -- Callback none
    Curly:SetOptNumber( CURLOPT_*, value )
    
    -- Takes 1:
    --     Username String
    -- Returns 1:
    --     Error Code - 0 means OK
    -- Callback none
    Curly:SetUsername( username )
    
    -- Takes 1:
    --     Password String
    -- Returns 1:
    --     Error Code - 0 means OK
    -- Callback none
    Curly:SetPassword( password )
    
    -- Takes 1:
    --     Data String - Can contain NULL Characters
    -- Returns 1:
    --     Error Code - 0 means OK
    -- Callback none
    Curly:SetPostFields( data )
    
    
    --------------------------------------------------------------------
    
    
    -- Takes 0:
    --     
    -- Returns 1:
    --     Returns data size.
    -- Callback none
    BinRead:GetSize( )
    
    -- Takes 0:
    --     
    -- Returns 1:
    --     Returns the position of the next item to be read.
    -- Callback none
    BinRead:GetReadPosition( )
    
    -- Takes 0:
    --     
    -- Returns 1:
    --     Returns the Read Position to 0
    -- Callback none
    BinRead:Rewind( )
    
    -- Takes 0:
    --     
    -- Returns 1:
    --     Reads 1byte, but does not change the Read Position
    -- Callback none
    BinRead:PeekByte( )
    
    -- Takes 0:
    --     
    -- Returns 1:
    --     Reads 1bytes and returns it as a int.
    -- Callback none
    BinRead:ReadByte( )
    
    -- Takes 0:
    --     
    -- Returns 1:
    --     Reads 8bytes and returns it as a double.
    -- Callback none
    BinRead:ReadDouble( )
    
    -- Takes 0:
    --     
    -- Returns 1:
    --     Reads 4bytes and returns it as a int.
    -- Callback none
    BinRead:ReadInt( )
    
    -- Takes 0:
    --     
    -- Returns 1:
    --     Reads 4bytes and returns it as a float.
    -- Callback none
    BinRead:ReadFloat( )
    
    -- Takes 0:
    --     
    -- Returns 1:
    --     Reads a NULL terminated string. Read Position will be offset by string.len + 1 (the extra NULL char)
    -- Callback none
    BinRead:ReadString( )
    





    Basic HTTP connection example.

    require("curly")
    
    local curl = Curly()
    curl:SetUrl("http://www.google.com/")
    curl:SetOptNumber(CURLOPT_FOLLOWLOCATION, 1)
    curl:SetCallback(function(curlObj, errorCode, data)
        print(curlObj, "\n", errorCode,"\n")
        Msg(data)
    end)
    curl:Perform()
    





    Basic HTTPS connection example.

    require("curly")
    
    local curl = Curly()
    curl:SetUrl("https://www.gmail.com/")
    curl:SetOptNumber(CURLOPT_FOLLOWLOCATION, 1)
    curl:SetOptNumber(CURLOPT_SSL_VERIFYPEER, 0)
    curl:SetOptNumber(CURLOPT_SSL_VERIFYHOST, 1)
    curl:SetCallback(function(curlObj, errorCode, data)
        print(curlObj, "\n", errorCode,"\n")
        Msg(data)
    end)
    curl:Perform()
    





    Some notes.

    Only one operation can happen at once on an Curly object.

    Once you call Curly:Perform(), you must wait for the the Callback before performing another Curl Query.

    All the functions are non-blocking.




    Reply With Quote Edit / Delete Reply Australia Show Events Useful Useful x 2 (list)

  2. Post #2
    Gold Member
    LuaStoned's Avatar
    September 2007
    1,300 Posts
    Sweeeet, can't wait to get home :D (~10min)

  3. Post #3
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    Hellyeah!

    Ive been waiting for this a long time!

    Edited:

    This is fucking incridible
    Reply With Quote Edit / Delete Reply Sweden Show Events Disagree Disagree x 1 (list)

  4. Post #4
    Prefan's Avatar
    January 2009
    1,000 Posts
    Having FTP upload support would be awesome with this.

  5. Post #5
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    it seems to add double \n though...

  6. Post #6
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    Double \n?

    Its probally a curl setting.

  7. Post #7
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    Actually no, its my file writing method that dosent accept \r or something

    Edited:

    Sadly gsub dosent seem to like strings anymore
    data:gsub("\r", "")

    produce "SK" what the

    Edited:

    Actually once again: no, its just IBaseFileSystem not liking anything today

  8. Post #8

    March 2007
    59 Posts
    Haza, nice module.

    Any chance you can do a libmemcache? You seem to be a capable person.

    Thanks.

  9. Post #9
    Gold Member
    LuaStoned's Avatar
    September 2007
    1,300 Posts
    Nevermind, you need the VS2010 Runtime..

  10. Post #10
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    We seriously need the ability to receive NULL's, in the worst case senario could you supply us with some bf_read style function and the ability to get the length so we could assemble the string ourselves for now?

    Edited:

    Oh nice 1500 posts!

  11. Post #11
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    I'm going to add Curly:SetBinaryMode(true), so instead of receiving a string, you will get a bf_read like object. I will also do the same for oosocks.

  12. Post #12
    Gold Member
    Gbps's Avatar
    December 2008
    3,437 Posts
    I'm going to add Curly:SetBinaryMode(true), so instead of receiving a string, you will get a bf_read like object. I will also do the same for oosocks.
    Make sure to add a few binary read and write functions too. It's kind of useless without it :S
    Reply With Quote Edit / Delete Reply United States Show Events Dumb Dumb x 1 (list)

  13. Post #13
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    Added Binary Read Functionality.

  14. Post #14
    Gold Member
    LuaStoned's Avatar
    September 2007
    1,300 Posts
    Added Binary Read Functionality.
    Cool stuff, now the serverbrowser/rcon/msn libs will finally get some functionallity :D

    €dit: Wanna give us an example?

  15. Post #15
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    Would it be possible to get the size of it so we can assemble the string with string.char?

  16. Post #16
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    Would it be possible to get the size of it so we can assemble the string with string.char?
    Curly:SetBinaryMode(true)
    Curly:SetCallback(function(obj, erroCode, binread)
        local size = binread:GetSize()
        local str = ""
        for i=1, size do
            str = str .. string.char(binread:GetByte())
        end
    end)
    

  17. Post #17
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    Ah nice, now we can download zips!
    Reply With Quote Edit / Delete Reply Sweden Show Events Disagree Disagree x 1 (list)

  18. Post #18
    Gold Member
    LuaStoned's Avatar
    September 2007
    1,300 Posts
    Now we just rely on people and how they set up their addons

  19. Post #19
    Grocel's Avatar
    October 2008
    1,279 Posts
    Curly:SetBinaryMode(true)
    Curly:SetCallback(function(obj, erroCode, binread)
        local size = binread:GetSize()
        local str = ""
        for i=1, size do
            str = str .. string.char(binread:GetByte())
        end
    end)
    
    Nice, will you also add this to gm_oosocks soon?

  20. Post #20
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    Just did.

  21. Post #21
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    It almost works, it fails on me when i try to download a zip though (probbably a file.Write problem)

  22. Post #22
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    You cant write binary data through file.Write
    Reply With Quote Edit / Delete Reply Australia Show Events Agree Agree x 1 (list)

  23. Post #23
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    Obviously your wrong

    BECUSE I CAN!

    Also would it be possible to decrypt it faster? Currently it lags like hell for a second while it decrypts that binread

    Edited:

    Apparantly it can only sometimes write NULL's

    what the shit(i can download a bz2 that contains nulls but not zips)

    Edited:

    Actually file.Write didnt like large files

    Edited:

    Could you make a function that reads a string until NULL, with this we could decode the BinRead without lagging everything to shit
    Reply With Quote Edit / Delete Reply Sweden Show Events Dumb Dumb x 1 (list)

  24. Post #24
    Gold Member
    LuaStoned's Avatar
    September 2007
    1,300 Posts
    Yeah, something like
    local out = {}
    for k,part in pairs(data:ReadStr()) do
    	table.insert(out,part)
    end
    write(table.concat(out,"\0"))

  25. Post #25
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    Ok.

  26. Post #26
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    I got how that would work, it would be like
    local size = data:GetSize()
    local str = ""
    debug.sethook()
    while true do
    if data:GetReadPosition() > size then
    break
    end
    str = str..data:ReadString()
    end

    Edited:

    Would be alot faster in most cases inless the file is made out of nulls

    Edited:

    Actually i got an idea:

    BinRead:ToTable()

    example:

    local str = ""
    for k, v in pairs(data:ToTable())
    str = str..string.char(v)
    end

  27. Post #27
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    Ok, Added ReadString to BinRead

  28. Post #28
    Gold Member
    LuaStoned's Avatar
    September 2007
    1,300 Posts
    Actually i got an idea:

    BinRead:ToTable()

    example:

    local str = ""
    for k, v in pairs(data:ToTable())
    str = str..string.char(v)
    end
    What no, string concatenation is extremely inefficient compared to table concat...

    Ok, Added ReadString to BinRead
    Thanks.

  29. Post #29
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    Would ToTable be hard to code and/or would it be slow?

  30. Post #30
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    Slow. 50k elements, all being bytes would kill it for sure.

  31. Post #31
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
        debug.sethook()
        while true do
            if binread:GetReadPosition() > size then
                break
            end
            table.insert(out,binread:ReadString())
        end
        local str = table.concat(out,"\0")

    Froze my game for 20 seconds and then gave me a "out of memory" error in console :ohdear:

  32. Post #32
    Gold Member
    LuaStoned's Avatar
    September 2007
    1,300 Posts
        debug.sethook()
        while true do
            if binread:GetReadPosition() > size then
                break
            end
            table.insert(out,binread:ReadString())
        end
        local str = table.concat(out,"\0")

    Froze my game for 20 seconds and then gave me a "out of memory" error in console :ohdear:
    Code:
    String concatenation, 25.000 times
    It took 3.11 seconds to finish!
    Table concatenation, 25.000 times
    It took 0.02 seconds to finish!

  33. Post #33
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    Must been that loop then

    Edited:

        local size = binread:GetSize()
        local out = {}
        debug.sethook()
        while true do
            if binread:GetReadPosition() >= size then
                break
            end
            table.insert(out,binread:ReadString())
        end
        local str = table.concat(out,"\0")
        if binread:GetReadPosition() == size then
            str = str..string.char(binread:ReadByte())
        end

    Very fast, but the code isnt very clean

    Edited:

    When i try to download a zip, 30 bytes is missing (probably file.Write glitchup)

    Edited:

    Ah yesm file.Write glitch

    Edited:

    0.00128173828125 seconds to decode 45kb of data

  34. Post #34
    Grocel's Avatar
    October 2008
    1,279 Posts
    If file.write doesn't work then try this: http://www.facepunch.com/showthread.php?t=970999
    ;)

  35. Post #35
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    i got my own function for it, it was just windows being an asshole becuse i didnt open the file in binary mode

  36. Post #36
    Gold Member

    April 2009
    721 Posts
    Error report:

    Lua: error loading module 'curly' from file 'c:\program files\steam\steamapps\*******\garrysmod\garrysmod\ lua\includes\modules\gm_curly.dll':
    Det angivne modul blev ikke fundet.

    Windows 7
    32 bit
    Need more info?

  37. Post #37
    Gold Member
    Tobba's Avatar
    December 2008
    5,573 Posts
    get the VC++ 2010 runtime package

  38. Post #38
    Gold Member

    April 2009
    721 Posts
    get the VC++ 2010 runtime package
    Right, that worked. Thanks

  39. Post #39
    Box collector
    haza55's Avatar
    October 2005
    545 Posts
    Updated DLL to use msvc 2008 dependencies.