Writing a HTTP chat program

I am behind a firewall/proxy at school, and the only port open is 80, the HTTP port.

Now I want to write a chat program to connect to a server outside our local network and beyond the firewall, so I assume I'll have to use HTTP to accomplish this.
What components do I have to use (I have FPiette's and the standard Delphi 4 Internet components) and how do I write my program?

Rico

(P.S: This program should not interfere with the Internet Explorer if possible. We connect to the proxy at 192.168.0.1:80)
LVL 1
nricoAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

GwenaCommented:
listening :-)
0
PeterLarsenCommented:
Your problem is to go through the proxy-server. I guess you know that.
Do you have a server program (web server) ??

For the server i would use TServerSocket and for the client i would use TNmHttp or TClientSocket.

Please give us some details !

Peter
0
Dmitry_Commented:
You can use ICQ and connect thru ICQ Proxy server, for details see http://icqproxy.com/
Or use web ICQ, see http://come.to/webicq
0
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

nricoAuthor Commented:
Yes, the problem lies with connecting thru the proxy, but that's because all ports have been closed.
Can I simply use TNmHttp to connect to any IP (Using the proxy settings) to connect to a TServerSocket listening at port 80? And that does not interfere with any Explorers I might be running?

(How exactly do I use TNmHttp, the thing puzzled me extremely..)
0
yk030299Commented:
listen
0
bryan7Commented:
""And that does not interfere with any Explorers I might be running? ""
maybe UDP would be a solution for that since udp is connectionless.. you don't have to connect before sending data.. maybe it would interfer only when browsing internet.. so you should only chat at a time, and browse at another. you could disable data receiving with a button when you want to browser internet

just an idea.
0
333Commented:
80 port is default for HTTP protocol, but this doesn't mean that you can use only HTTP on this port.
if your proxy opens this port not only for http, you can use another component i.e TNMMsg/TNMMsgServ or TNMStrm/TNMStrmServ which are easier to use for chat. Just set their port values to 80.
0
PeterLarsenCommented:
Nrico,

Http is the answer - the port number is not very important here, because you connect from behind the proxy-server. I would not use port 80 because the server you are connecting to maybe already have a web-server listening on that port.

If you use TNmHttp and want to connect through a proxy-server you most do something like this :
NMHTTP1.Host:='www.MyChatHost.xx' or IP-number
NMHTTP1.Port:=Port no. the host (MyChatHost) is listening on
NMHTTP1.Proxy:=Your Proxy-Server name or IP-number
NMHTTP1.ProxyPort:=Port no. to proxy-server.

Good luck
Peter
0
nricoAuthor Commented:
Okay, but all of the proxies ports (besides 80) are closed as well (it's only incidental that we connect to the proxy at port 80).
I figure I can use TNmHttp to establish the connection, but when I POST some data to a running TServerSocket I get some stuff like:

POST / HTTP/1.0
Accept: (forgot)
Content-size: 23

(the string i sent)

with some more crap and then the component hangs, apparently waiting for a reply.
What do I send back?

(If I connect to the TServerSocket using the IE, it also mentions:
Connection: keep-alive)

Help!
What is the proper response?
And why can't I establish a steady connection with a TNmHttp? I can only POST or GET, so to write a chat program I'll have to GET constantly (though that's not a real problem, I can do that).
0
PeterLarsenCommented:
I have read your comment and will reply tomorrow.
0
PeterLarsenCommented:
Hi Nrico - my comments in random order :

You cant use GET if you want to use Keep-alive.
If you'r going through a proxy-server i dont think it will be a good idea to have "live" chat, because it may hold to many connections.
I think it would be better if the clients polling the server for messages.

That text (POST / HTTP/1.0  ....) is the HTTP header. You need that because you'r going through the proxy-server. In the header the proxy-server read what to do with it (where to send it).

It is easy to use TNmHttp but sometimes its better to use TClientSocket.

A sample of a message (include HTTP header) :
var
 S : string;
begin
S:='POST HTTP://www.chatserver.xx:80/ HTTP/1.0'+#13#10+
'Date: Tuesday, 01-Feb-00 09:16:34 GMT '+#13#10+  //not important
'Host: :www.chatserver.xx:80'+#13#10+
'Connection: close'+#13#10+ //or keep-alive
'Content-Type: text/html'+#13#10+
'Pragma: No-Cache'+#13#10+
'Content-Length: 10'+#13#10+#13#10;
//Two newlines marks the end of HTTP header
//Now to the body/message
s:=s+'Test      '; //10 characters, like in Content-Length

Your server should reply something like this :
var
 S : string;
begin
S:='HTTP/1.1 200 OK'+#13#10+
'Date: Tuesday, 01-Feb-00 09:28:34 GMT'+#13#10+ //not important
'Connection: close'+#13#10+
'Content-Type: text/html'+#13#10+#13#10;

You may read all about HTTP 1.0 and 1.1 here :
http://www.ietf.org/rfc/rfc1945.txt
http://www.ietf.org/rfc/rfc2616.txt

About TClientSocket and TServerSocket you should use NONBLOCKING. Remember to use its OnRead and OnWrite (OnClientRead/OnClientWrite) when it is possible.
TServerClient create threads to handle each connection. It is probably there you have the problem.

Good luck
Peter
0
nricoAuthor Commented:
Isn't it easier to use TClientSocket/TServerSocket and tell the proxy to establish a connection AND keep it open? (There must be some way of doing this, perhaps by using the HTTP-header.)
From what I understand, the server has to close the connection, right?

I've tried a bit using the Netmasters' compontents (and FPiette's), and I have problems with:
1) Reading in the data. ReceiveText() gives me the whole header at once, then blank, and then the POST (I believe), sometimes it does not.
2) Determining when the POST is finished, so when I need to reply.
3) Actually replying. I can't get either HTTP component to understand the document I'm sending, and I'm using "Entity-Body: <whatevertext>".
4) Closing the connection. I use Socket.Close, but my HTTP components still hang.

(Maybe I'd indeed better use the TClientSocket also for the client part of the HTTP connection).
0
PeterLarsenCommented:
It is possible to keep the connection open, but it is not supported in http 1.0 - however MS-prosy-server 1.0 do support keep-alive.

If the server (TClientSocket) reply with "Connection : keep-alive" and the proxyserver supports it, the connection is not closed. You also need to include "Connection : keep-alive" in the client stream.

1:
Every time you receive data, you should put it in a buffer (S:=S+Text). Then search for 2 new lines in the text :
S:=S+Socket.ReceiveText;
if HeaderOK = false then
begin
 if (pos(#13+#10+#13+#10, S) > 0) or
    (pos(#10+#10, S) > 0) then
 begin
  HeaderOK:=true;
 //The header has arrived. There are some functions you may use to extract the header from the entire message or you may want to do it yourself.

2:
Use the line "Content-Length: XX" to see how many bytes that will be sent after the header.
If you are using "Connection : close" you can assume a successfully POST when the connection is disconnected - except if you receive a error-event.

3:
It is possible to launch both the client and the server component from one application. In other words - you should create a test application from where you may test how the client/server communicates.

4:
If you post a message from the client and the server dont reply on that the client may seem to hang.
You should include a timer on the server that checks all connections to see if they should be timedout (disconnected).

The components have several events - thay are very useful - so use them!!

TNmHttp is easier to use, but it has its limitations.

Peter
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
nricoAuthor Commented:
I've been coding my paws off for the last few days trying to implement SOCKS.
Turns out our proxy doesn't support it... :->

Ah well...
I have written the complete program (based on a TCP/IP connection though), so I'd rather have a steady connection.

Isn't there some way to let my program wear the guise of a HTTP program when it issues the connection request to the server and then simply keeps the connection open so I can send anything I want through it?
(The program will be for a limited group so there's no need to be worried about eating up resources)
0
PeterLarsenCommented:
>>Isn't there some way to let my program wear the guise of a HTTP program when it issues the connection request to the server and then simply keeps the connection open so I can send anything I want through it?

Please re-write that :)
0
nricoAuthor Commented:
Nevermind (I was in a poetic mind).
0
PeterLarsenCommented:
:-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.