Threadsafe Libcurl HTTPS Post

Just starting out? Need help? Post your questions and find answers here.
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Threadsafe Libcurl HTTPS Post

Post 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
infratec
Always Here
Always Here
Posts: 7584
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Threadsafe Libcurl HTTPS Post

Post 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 :wink:

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
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Threadsafe Libcurl HTTPS Post

Post by Olliv »

infratec wrote:And don't use stuff which you not know how to use :mrgreen:
:?

cURL option type declaring is explicite, what it means it is ok, without lagging the performances.
infratec
Always Here
Always Here
Posts: 7584
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Threadsafe Libcurl HTTPS Post

Post by infratec »

I meant the 'global' use of 'Threaded' to make it 'safer'.
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Threadsafe Libcurl HTTPS Post

Post by djes »

infratec wrote:Hi,

Code: Select all

str2curl()
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...
infratec
Always Here
Always Here
Posts: 7584
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Threadsafe Libcurl HTTPS Post

Post 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
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Threadsafe Libcurl HTTPS Post

Post 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...
infratec
Always Here
Always Here
Posts: 7584
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Threadsafe Libcurl HTTPS Post

Post 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.
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Threadsafe Libcurl HTTPS Post

Post 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 ! :)
infratec
Always Here
Always Here
Posts: 7584
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Threadsafe Libcurl HTTPS Post

Post 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 :mrgreen:
(It worked)

Bernd
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Threadsafe Libcurl HTTPS Post

Post by djes »

Yep, it works and it will, as long as pokes() and peeks() stops on first 0 :mrgreen:

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))
User avatar
kenmo
Addict
Addict
Posts: 2033
Joined: Tue Dec 23, 2003 3:54 am

Re: Threadsafe Libcurl HTTPS Post

Post 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 !!!
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Threadsafe Libcurl HTTPS Post

Post 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
User avatar
kenmo
Addict
Addict
Posts: 2033
Joined: Tue Dec 23, 2003 3:54 am

Re: Threadsafe Libcurl HTTPS Post

Post 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!
infratec
Always Here
Always Here
Posts: 7584
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Threadsafe Libcurl HTTPS Post

Post 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 :wink:

Bernd
Post Reply