I am playing arround with https://dweet.io/ - the concept is that you can send/post some fields/values to dweet.io and you can see those values published directly there or even see those data as graphical gauges in https://freeboard.io/. For the former no registration is required; data is published directly.
Example with curl:
$curl 'https://dweet.io/dweet/for/:kpv1?volt1=622&volt2=624&volt3=600'
#response:
{"this":"succeeded","by":"dweeting","the":"dweet","with":{"thing":":kpv1","created":"2023-11-05T19:03:17.892Z","content":{"volt1":622,"volt2":624,"volt3":600},"transaction":"98967dcf-168d-4c78-a190-9476ff95e9cd"}}
The same result can be achieved if I enter in my browser the URL https://dweet.io/dweet/for/:kpv1?volt1=622&volt2=624&volt3=600. Visiting https://dweet.io/follow/:kpv1 shows the data posted previously.
I would like to make this function through Free Pascal/Lazarus using a simple post solution. I have tried below code in a simple GUI form with a TEdit and a TButton, but when I press the button nothing happens... dweet.io is not updated and my Edit1.Text remains empty. Also i got nothing on stderr.
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, opensslsockets, fphttpclient;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
URL, S : String;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
URL := 'https://dweet.io/dweet/for/:kpv1?volt1=922&volt2=924&volt3=900';
S := TFPCustomHTTPClient.SimplePost(URL);
Writeln(stderr, S);
Edit1.Text:=S;
end;
Any ideas what I am missing...?
Update:
Ok, the problem is the "thing" name that I was using in dweet.io. For a "thing" named :kpv1 the code breaks. If I change the name to kpv1 (removing the : char) the code works fine. So these two lines works fine when the colon is removed from kpv1:
URL := 'https://dweet.io/dweet/for/kpv1?volt1=922&volt2=924&volt3=900';
S := TFPCustomHTTPClient.SimplePost(URL);
// response received in Edit1.Text:
// {"this":"succeeded","by":"dweeting","the":"dweet","with":{"thing":"kpv1","created":"2023-11-05T20:09:47.833Z","content":{"volt1":922,"volt2":924,"volt3":900},"transaction":"7177dc55-a174-4edd-b88d-fd64cc4dad9f"}}
// Values posted to dweet.io for kpv1 can be visualized in address https://dweet.io/follow/kpv1
The problem is that you don't respect how a URI/URL in HTTP has to be constructed - in there the colon is a reserved character as per RFC 3986 and needs to be percent-encoded into
%3Awhen being part of the path, query, or fragmet/anchor. The same rule applies to other selected characters, too (especially if you want to express things like a whitespaceor a slash/or and ampersand&or a question mark?).So the whole remedy should be:
...which is unbound to FreePascal and dweet.io - it applies to HTTP knowledge. I'll add respective tags to your Q.
In FreePascal
httpprotocol.HTTPEncode()looks sane in terms of implementation, so you could do in general:Note: encode components of the URL, not the whole URL in general.