Page 1 of 2

CommStreams

Posted: Sun Nov 18, 2018 2:19 am
by DGDanforth
PROCEDURE NewStream (protocol, localAdr, remoteAdr: ARRAY OF CHAR;
OUT s: Stream; OUT res: INTEGER)
I have not been able to get CommStreams.NewStream("CommTCP", "", url, s, res) to succeed
for any url such as https://www.google.com/ or https://www.nytimes.com/.
res = invalidRemoteAdr = 3;

What am I doing wrong?

Re: CommStreams

Posted: Sun Nov 18, 2018 8:56 am
by Ivan Denisov
1. Out of the box you can not use encrypted resources like "https". Only possible to communicate with servers with "http" (Josef has the solution for SSL in the Http subsystem)
2. Then you need to specify the port after domain name :80

The old example, how I used this in the attachment.

Re: CommStreams

Posted: Sun Nov 18, 2018 9:34 am
by DGDanforth
Doug wrote:CommStreams.NewStream("CommTCP", "", url, s, res);
with
url = http://greenwoodfarm.com:80
still does not work
res=3
Ivan Denisov wrote:1. Out of the box you can not use encrypted resources like "https". Only possible to communicate with servers with "http" (Josef has the solution for SSL in the Http subsystem)
2. Then you need to specify the port after domain name :80

The old example, how I used this in the attachment.

Re: CommStreams

Posted: Sun Nov 18, 2018 2:36 pm
by Josef Templ
Doug, you must define the local address as:

"0.0.0.0:0"

The docu of CommTCP has the details. It must be noted that a computer in general can have more than one
IP addresses and it can provide more than one network interface card. Therefore in the general case it is required to
specify which one to use. If the loopback interface is used (localhost) than the server must be on the same machine as the client.
Only when you specify a real IP address or the wildcard 0.0.0.0 network traffic can leave your loal machine.

"For unspecified port numbers, a wildcard is used, directing the operating system to choose freely. For unspecified local addresses the local host's address "127.0.0.1" is used.
The special IP address "0.0.0.0" means all available IP addresses on the local machine (including "127.0.0.1"). This can be used for listening on all available network interfaces or for connecting to a server using any available network interface. In this case network traffic may leave the local machine.
"

- Josef

Re: CommStreams

Posted: Mon Nov 19, 2018 12:45 am
by Ivan Denisov
It should be

Code: Select all

url := "greenwoodfarm.com:80"

Re: CommStreams

Posted: Mon Nov 19, 2018 3:15 am
by DGDanforth
Doug wrote: CommStreams.NewStream("CommTCP", "0.0.0.0:0", "greenwoodfarm.com:80", s, res);
ASSERT(res = 0);
TRAPs with res=3

Re: CommStreams

Posted: Mon Nov 19, 2018 5:42 am
by Ivan Denisov

Code: Select all

MODULE TestDoug;

	IMPORT CommStreams, Log;

	VAR s: CommStreams.Stream;
		
	PROCEDURE Do*;
	VAR res: INTEGER;
	BEGIN
		CommStreams.NewStream("CommTCP", "0.0.0.0:0", "greenwoodfarm.com:80", s, res);
		IF res = 0 THEN
			IF s # NIL THEN
				Log.String('connected well'); Log.Ln;
			END
		END
	END Do;

END TestDoug.
This returns connected well.
I tested only with Wine under GNU/Linux Debian 9.4.
However I think, that this should work on Windows as well.

Do you have some firewalls? Also do check with AntiVirus off.

Re: CommStreams

Posted: Mon Nov 19, 2018 5:53 am
by cfbsoftware
I ran a similar test on Windows 10 and it worked fine for me as well. If your code does not work on Doug's system then I also believe it is likely to be something to do with his Internet setup. Would a Proxy setting also be a possible culprit?

Re: CommStreams

Posted: Mon Nov 19, 2018 7:07 am
by Josef Templ
Works fine for me too.
Doug, it seems like there is a proxy configured. This means that you cannot access the remoteAdr directly but
only indirectly via an auxiliary node called a proxy.
If that is the case, you must use the the proxy's IP and port as remoteAdr.
You can use the test program below for testing with a proxy.

Code: Select all

MODULE TestHttpClient;

IMPORT CommStreams, Views, TextViews, TextModels;

CONST CRLF = "" + 0DX + 0AX;

PROCEDURE Do*;
	VAR stream: CommStreams.Stream;
		res, beg, len, i, written, read: INTEGER;
		request: ARRAY 256 OF CHAR;
		buf: ARRAY 2000 OF BYTE;
		t: TextModels.Model; w: TextModels.Writer;
		remoteAdrOrProxy: ARRAY 32 OF CHAR;
BEGIN
	remoteAdrOrProxy := "greenwoodfarm.com:80";
	CommStreams.NewStream("CommTCP", "0.0.0.0:0", remoteAdrOrProxy, stream, res);
	ASSERT(stream # NIL);
	ASSERT(res = 0);
	ASSERT(stream.IsConnected());
	request := "GET http://greenwoodfarm.com:80/ HTTP/1.0" + CRLF
		+ "Host: greenwoodfarm.com" + CRLF
		+ CRLF;
	(* write http request *)
	beg := 0; len := LEN(request$);
	FOR i := 0 TO len - 1 DO buf[i] := SHORT(SHORT(ORD(request[i]))) END;
	WHILE stream.IsConnected() & (len > 0) DO
		stream.WriteBytes(buf, beg, len, written);
		INC(beg, written); DEC(len, written)
	END;
	(* read http response header and body; ignores encoding *) 
	t := TextModels.dir.New();
	w := t.NewWriter(NIL);
	WHILE stream.IsConnected() DO
		stream.ReadBytes(buf, 0, LEN(buf), read);
		FOR i := 0 TO read - 1 DO w.WriteChar(CHR(buf[i])) END
	END;
	stream.Close;
	Views.OpenAux(TextViews.dir.New(t), "Response")
END Do;

END TestHttpClient.

^Q TestHttpClient.Do
- Josef

Re: CommStreams

Posted: Mon Nov 19, 2018 7:16 am
by DGDanforth
I ran Chris' program and it worked!

Ah, ha! I found I had in my code an extra space after :80

I couldn't see it. For what its worth I will be having
cataract surgery in a couple of months since edges
of fill-in fields are starting to disappear and commas and
periods look alike.

Doug