Skip to content

Commit

Permalink
v1.42
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeduglas committed Jan 22, 2019
1 parent 7974c76 commit 8ec434f
Show file tree
Hide file tree
Showing 12 changed files with 329 additions and 5 deletions.
12 changes: 12 additions & 0 deletions README.md
Expand Up @@ -30,6 +30,18 @@ Click on the Save icon 'floppy disk' and the Green arrow to close.


## Recent changes
v1.42
- CHG: Now uses libcurl v7.63.0, see [changelog](https://curl.haxx.se/changes.html) for details.
> curl 7.63.0 was built and statically linked with
>
> * OpenSSL 1.1.1a
> * brotli 1.0.7
> * libssh2 1.8.0
> * nghttp2 1.35.1
> * zlib 1.2.11
- NEW: TCurlUrlApiClass supports new [URL API](https://github.com/curl/curl/wiki/URL-API).
- NEW: URL API example.

v1.41
- NEW: CURLOPT_FILETIME, CURLOPT_FILE, CURLOPT_INFILE, CURLOPT_WRITEHEADER options.
- FIX: TCurlClass.GetInfo::DOUBLE() method called curl_easy_getinfo() with wrong parameters.
Expand Down
Binary file modified bin/libcrypto-1_1.dll
Binary file not shown.
Binary file modified bin/libcurl.dll
Binary file not shown.
Binary file modified bin/libssl-1_1.dll
Binary file not shown.
87 changes: 87 additions & 0 deletions examples/URL API/urlapi.clw
@@ -0,0 +1,87 @@
PROGRAM

OMIT('***')
* Created with Clarion 10.0
* User: Mike
* Date: 22.01.2019
* Time: 15:59
***

PRAGMA('project(#pragma link(libcurl.lib))')
INCLUDE('libcurl.inc')

MAP
GetUrlPart(CURLUPart what, UNSIGNED flags = 0), STRING
PrintUrlParts()
END


uapi TCurlUrlApiClass
url STRING('https://example.com:449/foo/bar?name=moo')
rc CURLUcode, AUTO



CODE
!Create a handle that holds URL info and resources.
uapi.Init()

!If successful, this stores the URL in its individual parts within the handle.
rc = uapi.SetPart(CURLUPART_URL, url, 0)
IF rc = CURLUE_OK
PrintUrlParts()

!Redirect to a relative URL.
!When the handle already has parsed a URL, setting a relative URL will make it "redirect" to adapt to it.
uapi.SetPart(CURLUPART_URL, '../test?another', 0)
curl::DebugInfo('Redirected URL: '& GetUrlPart(CURLUPART_URL))

!Set individual URL parts.
!A user can opt to set individual parts, either after having parsed a full URL or instead of parsing such.
uapi.SetPart(CURLUPART_USER, 'john', 0)
uapi.SetPart(CURLUPART_PASSWORD, 'doe', 0)
uapi.SetPart(CURLUPART_PATH, '/index.html', 0)
uapi.SetPart(CURLUPART_FRAGMENT, 'anchor', 0)
curl::DebugInfo('Modified URL: '& GetUrlPart(CURLUPART_URL))

!Append to the query.
!An application can append a string to the right end of the query part with the CURLU_APPENDQUERY flag.
uapi.SetPart(CURLUPART_QUERY, 'hat=1', CURLU_APPENDQUERY)
uapi.SetPart(CURLUPART_QUERY, 'shoes=2', CURLU_APPENDQUERY)
curl::DebugInfo('Appended URL: '& GetUrlPart(CURLUPART_URL))

!The appended string can of course also get URL encoded on add, and if asked, the encoding will skip the '=' character.
!For example, append candy=M&M to what we already have, and URL encode it to deal with the ampersand in the data:
uapi.SetPart(CURLUPART_QUERY, 'candy=M&M', CURLU_APPENDQUERY+CURLU_URLENCODE)
curl::DebugInfo('Encoded URL: '& GetUrlPart(CURLUPART_URL))
ELSE
MESSAGE('Parse failed, error '& rc)
END

!When done with it, clean it up
uapi.Cleanup() !-- not required, automatically called by destructor

MESSAGE('Done!')

GetUrlPart PROCEDURE(CURLUPart what, UNSIGNED flags = 0)
part STRING(256)
CODE
uapi.GetPart(what, part, flags)
RETURN CLIP(part)

PrintUrlParts PROCEDURE()
CODE
!Get individual URL parts.
!When a URL has been parsed or parts have been set, you can extract those pieces from the handle at any time.
!Extracted parts are not URL decoded unless the user asks for it with the CURLU_URLDECODE flag.

curl::DebugInfo('URL: '& GetUrlPart(CURLUPART_URL))
curl::DebugInfo('Scheme: '& GetUrlPart(CURLUPART_SCHEME))
curl::DebugInfo('User: '& GetUrlPart(CURLUPART_USER))
curl::DebugInfo('Password: '& GetUrlPart(CURLUPART_PASSWORD))
curl::DebugInfo('Options: '& GetUrlPart(CURLUPART_OPTIONS))
curl::DebugInfo('Host: '& GetUrlPart(CURLUPART_HOST))
curl::DebugInfo('Port: '& GetUrlPart(CURLUPART_PORT))
curl::DebugInfo('Path: '& GetUrlPart(CURLUPART_PATH))
curl::DebugInfo('Query: '& GetUrlPart(CURLUPART_QUERY))
curl::DebugInfo('Fragment: '& GetUrlPart(CURLUPART_FRAGMENT))
29 changes: 29 additions & 0 deletions examples/URL API/urlapi.cwproj
@@ -0,0 +1,29 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{D6CF98E5-1E14-4E55-A958-52DA5091208A}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">Win32</Platform>
<OutputType>Exe</OutputType>
<RootNamespace>urlapi</RootNamespace>
<AssemblyName>urlapi</AssemblyName>
<OutputName>urlapi</OutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>Full</DebugType>
<vid>full</vid>
<check_stack>True</check_stack>
<check_index>True</check_index>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<vid>off</vid>
<check_stack>False</check_stack>
<check_index>False</check_index>
</PropertyGroup>
<ItemGroup>
<Compile Include="urlapi.clw" />
</ItemGroup>
<Import Project="$(ClarionBinPath)\SoftVelocity.Build.Clarion.targets" />
</Project>
12 changes: 12 additions & 0 deletions history/changes.md
@@ -1,4 +1,16 @@
## Version history
v1.42
- CHG: Now uses libcurl v7.63.0, see [changelog](https://curl.haxx.se/changes.html) for details.
> curl 7.63.0 was built and statically linked with
>
> * OpenSSL 1.1.1a
> * brotli 1.0.7
> * libssh2 1.8.0
> * nghttp2 1.35.1
> * zlib 1.2.11
- NEW: TCurlUrlApiClass supports new [URL API](https://github.com/curl/curl/wiki/URL-API).
- NEW: URL API example.

v1.41
- NEW: CURLOPT_FILETIME, CURLOPT_FILE, CURLOPT_INFILE, CURLOPT_WRITEHEADER options.
- FIX: TCurlClass.GetInfo::DOUBLE() method called curl_easy_getinfo() with wrong parameters.
Expand Down
Binary file modified lib/libcurl.lib
Binary file not shown.
19 changes: 17 additions & 2 deletions libsrc/libcurl.clw
@@ -1,5 +1,5 @@
!** libcurl for Clarion v1.41
!** 07.12.2018
!** libcurl for Clarion v1.42
!** 22.01.2019
!** mikeduglas66@gmail.com

MEMBER
Expand Down Expand Up @@ -124,7 +124,13 @@


! curl_formget @17

! curl_free @18
! Provided for de-allocation in the same translation unit that did the
! allocation. Added in libcurl 7.10
curl_free(LONG p), C, RAW, NAME('curl_free')
curl_free(*CSTRING p), C, RAW, NAME('curl_free')

! curl_getdate @19
! curl_getenv @20

Expand Down Expand Up @@ -243,6 +249,15 @@ curl::GlobalInit PROCEDURE(CURL_GLOBAL_ENUM pFlag = CURL_GLOBAL_DEF
curl::GlobalCleanup PROCEDURE()
CODE
curl_global_cleanup()
!!!endregion

curl::free PROCEDURE(LONG p)
CODE
curl_free(p)

curl::free PROCEDURE(*CSTRING p)
CODE
curl_free(p)

!!!endregion

Expand Down
75 changes: 73 additions & 2 deletions libsrc/libcurl.inc
@@ -1,5 +1,5 @@
!** libcurl for Clarion v1.41
!** 07.12.2018
!** libcurl for Clarion v1.42
!** 22.01.2019
!** mikeduglas66@gmail.com

INCLUDE('DynStr.inc'), ONCE
Expand Down Expand Up @@ -791,6 +791,11 @@ filled LONG !bytes written
curl::GlobalInit(CURL_GLOBAL_ENUM pFlag = CURL_GLOBAL_DEFAULT), CURLcode, PROC
curl::GlobalCleanup()
! Provided for de-allocation in the same translation unit that did the
! allocation. Added in libcurl 7.10
curl::free(LONG p)
curl::free(*CSTRING p)
curl::StrError(CURLcode errcode), STRING
END
Expand Down Expand Up @@ -1452,6 +1457,72 @@ SetSubparts PROCEDURE(curl_mimepart part, TCurlMimeClass sub
!!!<param name="pHugeData">pointer to the data bytes.</param>
!!!<param name="pDoDispose">call DISPOSE(pHugeData) after the transfer terminates.</param>
SetDataCB PROCEDURE(curl_mimepart part, CONST *STRING pHugeData, BOOL pDoDispose = FALSE), CURLcode, PROC
END

!---------------------------- TCurlUrlApiClass ----------------------------!
!https://github.com/curl/curl/wiki/URL-API

!the error codes for the URL API
CURLUcode EQUATE(LONG)
ITEMIZE
CURLUE_OK EQUATE(0)
CURLUE_BAD_HANDLE EQUATE(1)
CURLUE_BAD_PARTPOINTER EQUATE(2)
CURLUE_MALFORMED_INPUT EQUATE(3)
CURLUE_BAD_PORT_NUMBER EQUATE(4)
CURLUE_UNSUPPORTED_SCHEME EQUATE(5)
CURLUE_URLDECODE EQUATE(6)
CURLUE_OUT_OF_MEMORY EQUATE(7)
CURLUE_USER_NOT_ALLOWED EQUATE(8)
CURLUE_UNKNOWN_PART EQUATE(9)
CURLUE_NO_SCHEME EQUATE(10)
CURLUE_NO_USER EQUATE(11)
CURLUE_NO_PASSWORD EQUATE(12)
CURLUE_NO_OPTIONS EQUATE(13)
CURLUE_NO_HOST EQUATE(14)
CURLUE_NO_PORT EQUATE(15)
CURLUE_NO_QUERY EQUATE(16)
CURLUE_NO_FRAGMENT EQUATE(17)
END


CURLUPart EQUATE(LONG)
ITEMIZE(0)
CURLUPART_URL EQUATE
CURLUPART_SCHEME EQUATE
CURLUPART_USER EQUATE
CURLUPART_PASSWORD EQUATE
CURLUPART_OPTIONS EQUATE
CURLUPART_HOST EQUATE
CURLUPART_PORT EQUATE
CURLUPART_PATH EQUATE
CURLUPART_QUERY EQUATE
CURLUPART_FRAGMENT EQUATE
END

CURLU_DEFAULT_PORT EQUATE(0b) !return default port number
CURLU_NO_DEFAULT_PORT EQUATE(10b) !act as if no port number was set, if the port number matches the default for the scheme
CURLU_DEFAULT_SCHEME EQUATE(100b) !return default scheme if missing
CURLU_NON_SUPPORT_SCHEME EQUATE(1000b) !allow non-supported scheme
CURLU_PATH_AS_IS EQUATE(10000b) !leave dot sequences
CURLU_DISALLOW_USER EQUATE(100000b) !no user+password allowed
CURLU_URLDECODE EQUATE(1000000b) !URL decode on get
CURLU_URLENCODE EQUATE(10000000b) !URL encode on set
CURLU_APPENDQUERY EQUATE(100000000b) !append a form style part
CURLU_GUESS_SCHEME EQUATE(1000000000b) !legacy curl-style guessing


CURLU EQUATE(LONG)

TCurlUrlApiClass CLASS, TYPE, MODULE('libcurlurl.clw'), LINK('libcurlurl.clw')
urlp CURLU, PRIVATE

Construct PROCEDURE()
Destruct PROCEDURE(), VIRTUAL

Init PROCEDURE()
Cleanup PROCEDURE()
Dup PROCEDURE(TCurlUrlApiClass src)
GetPart PROCEDURE(CURLUPart what, *STRING part, UNSIGNED flags = 0), CURLUcode, PROC
SetPart PROCEDURE(CURLUPart what, STRING part, UNSIGNED flags = 0), CURLUcode, PROC
END
98 changes: 98 additions & 0 deletions libsrc/libcurlurl.clw
@@ -0,0 +1,98 @@
!** libcurl for Clarion v1.42
!** 22.01.2019
!** mikeduglas66@gmail.com

MEMBER

INCLUDE('libcurl.inc')

MAP
MODULE('URL API')
!/*
! * curl_url() creates a new CURLU handle and returns a pointer to it.
! * Must be freed with curl_url_cleanup().
! */
!CURL_EXTERN CURLU *curl_url(void);
curl_url(), CURLU, C, NAME('curl_url')

!/*
! * curl_url_cleanup() frees the CURLU handle and related resources used for
! * the URL parsing. It will not free strings previously returned with the URL
! * API.
! */
!CURL_EXTERN void curl_url_cleanup(CURLU *handle);
curl_url_cleanup(CURLU handle), C, NAME('curl_url_cleanup')

!/*
! * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new
! * handle must also be freed with curl_url_cleanup().
! */
!CURL_EXTERN CURLU *curl_url_dup(CURLU *in);
curl_url_dup(CURLU in), CURLU, C, NAME('curl_url_dup')

!/*
! * curl_url_get() extracts a specific part of the URL from a CURLU
! * handle. Returns error code. The returned pointer MUST be freed with
! * curl_free() afterwards.
! */
!CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what,
! char **part, unsigned int flags);
curl_url_get(CURLU handle, CURLUPart what, LONG part, UNSIGNED flags), CURLUcode, C, NAME('curl_url_get')

!/*
! * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns
! * error code. The passed in string will be copied. Passing a NULL instead of
! * a part string, clears that part.
! */
!CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what,
! const char *part, unsigned int flags);
curl_url_set(CURLU handle, CURLUPart what, *CSTRING part, UNSIGNED flags), CURLUcode, C, RAW, NAME('curl_url_set')
END
END

!!! region TCurlUrlApiClass
TCurlUrlApiClass.Construct PROCEDURE()
CODE
SELF.urlp = 0

TCurlUrlApiClass.Destruct PROCEDURE()
CODE
SELF.Cleanup()

TCurlUrlApiClass.Init PROCEDURE()
CODE
SELF.Cleanup()
SELF.urlp = curl_url()

TCurlUrlApiClass.Cleanup PROCEDURE()
CODE
IF SELF.urlp <> 0
curl_url_cleanup(SELF.urlp)
SELF.urlp = 0
END

TCurlUrlApiClass.Dup PROCEDURE(TCurlUrlApiClass src)
CODE
SELF.Cleanup()
SELF.urlp = curl_url_dup(src.urlp)

TCurlUrlApiClass.GetPart PROCEDURE(CURLUPart what, *STRING part, UNSIGNED flags = 0)
rc CURLUcode, AUTO
lppart LONG, AUTO
szpart &CSTRING
CODE
rc = curl_url_get(SELF.urlp, what, ADDRESS(lppart), flags)
IF rc = CURLUE_OK
szpart &= (lppart)
part = szpart
curl::free(lppart)
END

RETURN rc

TCurlUrlApiClass.SetPart PROCEDURE(CURLUPart what, STRING part, UNSIGNED flags = 0)
szpart CSTRING(LEN(CLIP(part)) + 1)
CODE
szpart = CLIP(part)
RETURN curl_url_set(SELF.urlp, what, szpart, flags)
!!!endregion
2 changes: 1 addition & 1 deletion template/libcurl.tpl
Expand Up @@ -4,7 +4,7 @@
#SHEET
#TAB('About')
#DISPLAY('Libcurl support')
#DISPLAY('(c) 2015-2017 by Mike Duglas')
#DISPLAY('(c) 2015-2019 by Mike Duglas')
#DISPLAY('home page: https://github.com/mikeduglas/libcurl')
#DISPLAY('email: mikeduglas66@gmail.com')
#DISPLAY('')
Expand Down

0 comments on commit 8ec434f

Please sign in to comment.