Page 2 of 3
Re: Threadsafe Libcurl HTTPS Post
Posted: Wed Jul 05, 2017 6:35 pm
by Fred
you can also use a specific import to handle utf8 via pseudotype so you don't need to use UTF8/FreeMemory() all the way. May be 'curl_easy_setopt_utf8' or something similar
Re: Threadsafe Libcurl HTTPS Post
Posted: Wed Jul 05, 2017 8:06 pm
by infratec
Hi Fred,
I tried this, but since this functions awaits also integer values it is not possible to use pseudo types.
Else an integer is converted
Code: Select all
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
Examples:
If option is CURLOPT_URL it needs an UTF8 pointer,
if option is CURLOPT_FOLLOWLOCATION it needs 0 or 1.
So
Code: Select all
curl_easy_setopt(handle.i, option.i, parameter.p-utf8)
is not possible. It needs to be
Code: Select all
curl_easy_setopt(handle.i, option.i, parameter.i)
Or is there an 'advanced' trick?
Bernd
Re: Threadsafe Libcurl HTTPS Post
Posted: Thu Jul 06, 2017 2:06 am
by Olliv
infratec wrote:And don't use stuff which you not know how to use
cURL option type declaring is explicite, what it means it is ok, without lagging the performances.
Re: Threadsafe Libcurl HTTPS Post
Posted: Thu Jul 06, 2017 7:03 am
by infratec
I meant the 'global' use of 'Threaded' to make it 'safer'.
Re: Threadsafe Libcurl HTTPS Post
Posted: Thu Jul 06, 2017 8:24 am
by djes
infratec wrote:Hi,
is also not thread safe.
Please note that
this one is thread safe, as our functions
http://www.purebasic.fr/english/viewtop ... 12&t=66099 and
http://www.purebasic.fr/english/viewtop ... 12&t=66527, already tested with a lot a simultaneous requests...
Re: Threadsafe Libcurl HTTPS Post
Posted: Thu Jul 06, 2017 11:06 am
by infratec
Hi dijes,
yes, your version is threadsafe, but...
It looks very strange to me:
1. you should use #PB_UTF8 instead of #PB_ASCII
2. you poke it in Ascii and read it back as unicode (default) with -1 as length.
But your buffer is only 1 byte longer and not 2. So only one 0 is at the end of the buffer.
A Unicode string has 0 0 at the end. I'm not sure if your PeekS is working all the time.
3. I'm not sure what's inside of the returned string since you read Unicode but it is Ascii/UTF8
but it may work as expected.
Bernd
Re: Threadsafe Libcurl HTTPS Post
Posted: Thu Jul 06, 2017 12:40 pm
by djes
infratec wrote:Hi dijes,
yes, your version is threadsafe, but...
It looks very strange to me:
1. you should use #PB_UTF8 instead of #PB_ASCII
2. you poke it in Ascii and read it back as unicode (default) with -1 as length.
But your buffer is only 1 byte longer and not 2. So only one 0 is at the end of the buffer.
A Unicode string has 0 0 at the end. I'm not sure if your PeekS is working all the time.
3. I'm not sure what's inside of the returned string since you read Unicode but it is Ascii/UTF8
but it may work as expected.
Bernd
I agree it could look strange. It is purely ASCII and by now should be adapted to UTF. To explain it, I simply considered that as the first result is ASCII, further operations are clamped to one byte/char. Should UTF8 really needing two 0 at the end of the buffer ? I don't see why...
Re: Threadsafe Libcurl HTTPS Post
Posted: Thu Jul 06, 2017 2:12 pm
by infratec
UTF8 needs only one 0.
But you read the buffer out with plan PeekS
Code: Select all
newstring = PeekS(*curlstring, -1)
So the type is Unicode and this requires two 0 at the end of the buffer.
Re: Threadsafe Libcurl HTTPS Post
Posted: Thu Jul 06, 2017 3:08 pm
by djes
infratec wrote:UTF8 needs only one 0.
But you read the buffer out with plan PeekS
Code: Select all
newstring = PeekS(*curlstring, -1)
So the type is Unicode and this requires two 0 at the end of the buffer.
Oh yes, you're right ; I should have been lucky or maybe the peeks() is working on byte ; I've fixed it in
http://www.purebasic.fr/english/viewtop ... 12&t=66527
Thank you !

Re: Threadsafe Libcurl HTTPS Post
Posted: Fri Jul 07, 2017 11:07 am
by infratec
The double 0 is needed:
Code: Select all
*Buffer = AllocateMemory(256)
If *Buffer
FillMemory(*Buffer,MemorySize(*Buffer), $FF)
PokeS(*Buffer, "Hello World")
ShowMemoryViewer(*Buffer, MemorySize(*Buffer))
FreeMemory(*Buffer)
EndIf
You are a lucky man
(It worked)
Bernd
Re: Threadsafe Libcurl HTTPS Post
Posted: Fri Jul 07, 2017 1:54 pm
by djes
Yep, it works and it will, as long as pokes() and peeks() stops on first 0
Code: Select all
string.s = "Purebasic"
*curlstring = AllocateMemory(Len(string) + 5)
FillMemory(*curlstring, MemorySize(*curlstring), $FF)
PokeS(*curlstring, string, -1, #PB_Ascii)
*newstring = AllocateMemory(Len(string) + 5)
FillMemory(*newstring, MemorySize(*newstring), $FF)
PokeS(*newstring, PeekS(*curlstring, -1)) ;Demo of both peeks() and pokes() showing that they stop on the first 0
ShowMemoryViewer(*newstring, MemorySize(*newstring))
Re: Threadsafe Libcurl HTTPS Post
Posted: Fri Jul 07, 2017 2:37 pm
by kenmo
No, PeekS() in Unicode definitely needs 2 NULLs to stop.
Your example is not working OK. But you're overwriting $FF with $FF so it doesn't show the problem.
See new comments:
Code: Select all
string.s = "Purebasic"
*curlstring = AllocateMemory(Len(string) + 5)
FillMemory(*curlstring, MemorySize(*curlstring), $FF) ; <----- fill *curlstring with $FF
PokeS(*curlstring, string, -1, #PB_Ascii)
*newstring = AllocateMemory(Len(string) + 5)
FillMemory(*newstring, MemorySize(*newstring), $AA) ; <----- fill *newstring with $AA
PokeS(*newstring, PeekS(*curlstring, -1)) ; <---- PeekS() needs 2 NULLs, so this will pick up extra $FFs
ShowMemoryViewer(*newstring, MemorySize(*newstring)) ; <----- $AA covered with $FF !!!
Re: Threadsafe Libcurl HTTPS Post
Posted: Fri Jul 07, 2017 3:25 pm
by djes
Yes, thank you to demonstrate this mistake ! While testing peeks() about these two zeros, I discovered something that reinforce for me the need to only use safe string functions, or to be sure to be on 2 bytes boundaries... Uncomment the second PokeB to see :
Code: Select all
string.s = "Purebasic"
*curlstring = AllocateMemory(Len(string) + 5)
FillMemory(*curlstring, MemorySize(*curlstring), $FF)
PokeS(*curlstring, string, -1, #PB_Ascii)
PokeB(*curlstring + Len(string) + 1, 0)
;PokeB(*curlstring + Len(string) + 2, 0) ;One more to be sure ;)
*newstring = AllocateMemory(Len(string) + 5)
FillMemory(*newstring, MemorySize(*newstring), $AA)
PokeS(*newstring, PeekS(*curlstring, -1))
ShowMemoryViewer(*newstring, MemorySize(*newstring))
Peeks() stops only on a two null CHARACTER, not on two null bytes.
What do you think of this ?
Code: Select all
Procedure.s str2curl(string.s)
Protected NewString.s = string ; The final string is a copy of PB native unicode string, whose size is double of the ASCII final one
Protected *buf, l = Len(string)
*buf = Ascii(string)
If *buf
CopyMemory(Ascii(string), @newstring, l) ; Conversion
;FillMemory(@NewString + l, l * (SizeOf(CHARACTER) - 1), 0) ; Clear to the end the string buffer or ...
PokeB(@NewString + l, 0) ; ... only add a final 0 to end the ASCII string (faster)
FreeMemory(*buf)
;ShowMemoryViewer(@NewString, (Len(string) + 1) * SizeOf(CHARACTER))
ProcedureReturn NewString
EndIf
EndProcedure
Re: Threadsafe Libcurl HTTPS Post
Posted: Fri Jul 07, 2017 6:14 pm
by kenmo
Your example still has problems, because you're still Poking ASCII data but Peeking it as Unicode (why are you doing that?)
2 $00 bytes (1 Unicode $0000 character) is correct to stop PeekS() in Unicode.
But in your last example, your $0000 bytes are spread over an odd-byte boundary, so PeekS() sees ($63 $00) ($00 FF) instead of ($00 $00).
Try this, add or remove 1 letter from the "Purebasic" string, and your results appear correct. But only for even-length ASCII strings!
Re: Threadsafe Libcurl HTTPS Post
Posted: Fri Jul 07, 2017 6:59 pm
by infratec
This should do it right:
Code: Select all
Procedure.s str2curl(Strings$)
Protected *Buffer, UTF8$
*Buffer = AllocateMemory(StringByteLength(Strings$, #PB_UTF8) + 3)
If *Buffer
PokeS(*Buffer, Strings$, -1, #PB_UTF8)
UTF8$ = PeekS(*Buffer, -1, #PB_Unicode)
FreeMemory(*Buffer)
EndIf
ProcedureReturn UTF8$
EndProcedure
But I'm not sure why it not results in an error.
Code: Select all
curl_easy_setopt(handle.i, option.i, parameter.i)
parameter is an integer and
Code: Select all
curl_easy_setopt(curl, #CURLOPT_URL, str2curl("https://"))
places a string as an integer.
But it works
Bernd