Re: [twsocket] GpHTTPProxy doesn't work correctly

2008-09-22 Thread Primož Gabrijelčič
Oh, it is that bug :((

Sorry for not including in the debate sooner, but I lost contact with
GpHttpProxy years ago when I started to work on a custom version for one of
my customers. Now I had no idea which of the problems I fixed years ago this
was (yes, I was not using source control at the time :( ).

The trick was to destroy remote socket and recreate it if host or port
changed.

I think this are the two most important parts:

procedure TGpHttpProxy.ProcessHeader(Client: TGpHttpProxyClient);
var
  ahost: string;
  aport: string;
  header   : string;
  returnContent: string;
  resetSocket  : boolean;
begin
  resetSocket := false;
  returnContent := '';
  header := Client.Received;
  if SameText(FirstEl(header,' ',-1),'CONNECT') then begin
// TCP Tunnel proxy request
HttpData(Client).ProxyType := ptTCPTunnel;
if not IPSec.IsAllowed(Client.PeerAddr) then
  returnContent := Response.sTCPTunnelIPForbidden.Text
else if not (ptTCPTunnel in EnabledTypes) then
  returnContent := Response.sTCPTunnelClosed.Text
else if not
ProcessTCPTunnelHeader(Client,header,ahost,aport,returnContent) then
  returnContent := Response.sTCPTunnelBadRequest.Text;
  end
  else begin
// HTTP proxy request
HttpData(Client).ProxyType := ptHTTP;
if not IPSec.IsAllowed(Client.PeerAddr) then
  returnContent := Response.sHTTPIPForbidden.Text
else if not (ptHTTP in EnabledTypes) then
  returnContent := Response.sHTTPClosed.Text
else if not
ProcessHTTPHeader(Client,header,ahost,aport,returnContent,resetSocket) then
  returnContent := Response.sHTTPBadRequest.Text;
  end; //else SameText()
  // Header parsed, create remote socket.
  if returnContent = '' then begin
if resetSocket then begin
  {$IFDEF LogHttpFlow}
  LogFlow(Client, 'Destroyed connection to %s:%s due to host/port
change',
[Client.RemoteHost, Client.RemoteSocket.Port]);
  {$ENDIF LogHttpFlow}
  Client.DestroyRemoteSocket;
  Client.NumRequests := 1;
end;
if not assigned(Client.RemoteSocket) then with Client do begin
  {$IFDEF LogHttpFlow}
  LogFlow(Client, 'Opening connection to %s:%s', [ahost, aport]);
  {$ENDIF LogHttpFlow}
  CreateRemoteSocket;
  RemoteHost:= ahost;
  RemoteSocket.Port := aport;
  RemoteSocket.LineMode := false;
  HookRemoteEvents(RemoteSocket);
  RemoteSocket.DnsLookup(ahost);
  DoRemoteSocketPrepared(Client);
end //with/if
else begin
  {$IFDEF LogHttpFlow}
  LogFlow(Client, 'Reusing connection to %s:%s', [Client.RemoteHost,
Client.RemoteSocket.Port]);
  {$ENDIF LogHttpFlow}
end;
{$IFDEF LogHttpFlow}
LogFlow(Client, 'Request: %s', [FirstEl(header, #13, -1)]);
{$ENDIF LogHttpFlow}
Client.Received := header;
  end
  else begin
Client.DestroyRemoteSocket;
Client.RemoteContent := returnContent;
  end;
  Client.GotHeader := true;
end; { TGpHttpProxy.ProcessHeader }

function TGpHttpProxy.ProcessHTTPHeader(Client: TGpHttpProxyClient; var
header, ahost,
  aport, returnContent: string; var socketResetRequired: boolean): boolean;

  function MakeUrl(aproto, auser, apass, ahost, aport, apath: string):
string;
  begin
Result := aproto;
if Last(Result,1) = ':' then
  Result := Result + '//'
else if Last(Result,1)  '/' then
  Result := Result + '://';
if auser  '' then begin
  Result := Result + auser;
  if apass  '' then
Result := Result + ':' + apass;
  Result := Result + '@';
end;
Result := Result + ahost;
if (aport  '') and (aport  '80') then
  Result := Result + ':' + aport;
Result := Result + apath;
  end; { MakeUrl }

var
  apass : string;
  apath : string;
  aproto: string;
  auser : string;
  command   : string;
  hdrHost   : string;
  ignoreNextHopProxy: boolean;
  p1: integer;
  p2: integer;
  s : string;
  url   : string;

begin { TGpHttpProxy.ProcessHTTPHeader }
  Result := false;
  socketResetRequired := false;
  // extract url from GET/POST header
  s := header;
  p1 := Pos(' ',s);
  if p1  0 then begin
command := First(s,p1-1);
Delete(s,1,p1);
s := TrimLeft(s);
p2 := Pos(' ',s);
if p2  0 then begin
  url := Copy(s,1,p2-1);
  ParseURL(url,aproto,auser,apass,ahost,aport,apath);
  if aport = '' then
aport := '80';
  hdrHost := ExtractHeader(header,'Host');
  returnContent := '';
  ignoreNextHopProxy := false;
 
DoClientHeaderAvailable(Client,url,header,aproto,auser,apass,ahost,aport,
apath,hdrHost,ignoreNextHopProxy,returnContent);
  if (NextHopHTTP.Address  '') and (not ignoreNextHopProxy) and
 (returnContent = '') then //replace host information with proxy
  begin
Delete(header,p1+1,p2-1);

Re: [twsocket] GpHTTPProxy doesn't work correctly

2008-09-22 Thread S.Korotky
Hello, Primoz!

I think the modified code can not solve the problem on its own, without further
modifications. The reason for this is that ProcessHeader procedure is called 
from
ReceivedFromClient if and only if Client.GotHeader is false, but it is set to
true after the very first invocation of the ProcessHeader, so it will not be
called for all subsequent requests in a given connection.

Best wishes,
Stanislav Korotky.

- Original Message - 
From: Primož Gabrijelčič [EMAIL PROTECTED]
To: 'ICS support mailing' twsocket@elists.org
Sent: Monday, September 22, 2008 10:06 AM
Subject: Re: [twsocket] GpHTTPProxy doesn't work correctly


Oh, it is that bug :((

Sorry for not including in the debate sooner, but I lost contact with
GpHttpProxy years ago when I started to work on a custom version for one of
my customers. Now I had no idea which of the problems I fixed years ago this
was (yes, I was not using source control at the time :( ).

The trick was to destroy remote socket and recreate it if host or port
changed.

I think this are the two most important parts:

procedure TGpHttpProxy.ProcessHeader(Client: TGpHttpProxyClient);
var
  ahost: string;
  aport: string;
  header   : string;
  returnContent: string;
  resetSocket  : boolean;
begin
  resetSocket := false;
  returnContent := '';
  header := Client.Received;
  if SameText(FirstEl(header,' ',-1),'CONNECT') then begin
// TCP Tunnel proxy request
HttpData(Client).ProxyType := ptTCPTunnel;
if not IPSec.IsAllowed(Client.PeerAddr) then
  returnContent := Response.sTCPTunnelIPForbidden.Text
else if not (ptTCPTunnel in EnabledTypes) then
  returnContent := Response.sTCPTunnelClosed.Text
else if not
ProcessTCPTunnelHeader(Client,header,ahost,aport,returnContent) then
  returnContent := Response.sTCPTunnelBadRequest.Text;
  end
  else begin
// HTTP proxy request
HttpData(Client).ProxyType := ptHTTP;
if not IPSec.IsAllowed(Client.PeerAddr) then
  returnContent := Response.sHTTPIPForbidden.Text
else if not (ptHTTP in EnabledTypes) then
  returnContent := Response.sHTTPClosed.Text
else if not
ProcessHTTPHeader(Client,header,ahost,aport,returnContent,resetSocket) then
  returnContent := Response.sHTTPBadRequest.Text;
  end; //else SameText()
  // Header parsed, create remote socket.
  if returnContent = '' then begin
if resetSocket then begin
  {$IFDEF LogHttpFlow}
  LogFlow(Client, 'Destroyed connection to %s:%s due to host/port
change',
[Client.RemoteHost, Client.RemoteSocket.Port]);
  {$ENDIF LogHttpFlow}
  Client.DestroyRemoteSocket;
  Client.NumRequests := 1;
end;
if not assigned(Client.RemoteSocket) then with Client do begin
  {$IFDEF LogHttpFlow}
  LogFlow(Client, 'Opening connection to %s:%s', [ahost, aport]);
  {$ENDIF LogHttpFlow}
  CreateRemoteSocket;
  RemoteHost:= ahost;
  RemoteSocket.Port := aport;
  RemoteSocket.LineMode := false;
  HookRemoteEvents(RemoteSocket);
  RemoteSocket.DnsLookup(ahost);
  DoRemoteSocketPrepared(Client);
end //with/if
else begin
  {$IFDEF LogHttpFlow}
  LogFlow(Client, 'Reusing connection to %s:%s', [Client.RemoteHost,
Client.RemoteSocket.Port]);
  {$ENDIF LogHttpFlow}
end;
{$IFDEF LogHttpFlow}
LogFlow(Client, 'Request: %s', [FirstEl(header, #13, -1)]);
{$ENDIF LogHttpFlow}
Client.Received := header;
  end
  else begin
Client.DestroyRemoteSocket;
Client.RemoteContent := returnContent;
  end;
  Client.GotHeader := true;
end; { TGpHttpProxy.ProcessHeader }

function TGpHttpProxy.ProcessHTTPHeader(Client: TGpHttpProxyClient; var
header, ahost,
  aport, returnContent: string; var socketResetRequired: boolean): boolean;

  function MakeUrl(aproto, auser, apass, ahost, aport, apath: string):
string;
  begin
Result := aproto;
if Last(Result,1) = ':' then
  Result := Result + '//'
else if Last(Result,1)  '/' then
  Result := Result + '://';
if auser  '' then begin
  Result := Result + auser;
  if apass  '' then
Result := Result + ':' + apass;
  Result := Result + '@';
end;
Result := Result + ahost;
if (aport  '') and (aport  '80') then
  Result := Result + ':' + aport;
Result := Result + apath;
  end; { MakeUrl }

var
  apass : string;
  apath : string;
  aproto: string;
  auser : string;
  command   : string;
  hdrHost   : string;
  ignoreNextHopProxy: boolean;
  p1: integer;
  p2: integer;
  s : string;
  url   : string;

begin { TGpHttpProxy.ProcessHTTPHeader }
  Result := false;
  socketResetRequired := false;
  // extract url from GET/POST header
  s := header;
  p1 := Pos(' ',s);
  if p1  0 then begin
command := First(s,p1-1);
Delete(s,1,p1);
s := TrimLeft(s);
p2 := Pos(' ',s);
if 

Re: [twsocket] TWSocket Digest, Vol 287, Issue 11

2008-09-22 Thread John Grabner

Date: Sun, 21 Sep 2008 10:32:35 +0200
From: Francois PIETTE [EMAIL PROTECTED]
Subject: Re: [twsocket] Updating to C++Buulder2009
To: ICS support mailing twsocket@elists.org
Message-ID: [EMAIL PROTECTED]
Content-Type: text/plain; format=flowed; charset=iso-8859-1;
   reply-type=original

  

I am trying to get ICS to compile for C++Builder 2009. I am using the V7
Alpha as my base.



Are your using it from SVN repository ? If not, please do it. The repository 
has newer files compared to C++Builder Partner DVD which has files working 
with latest fieldtest while you use RTM.


  

I am now using the icsv7 branch from the SVN repository. I have built 
the project, using OverbyteIcsBcb120Package.cbproj, but had to remove 
OverbyteIcsPools.pas from the package. There where a few references to 
implicit casts from AnsiString to string and one implicit cast from 
string to AnsiString. It looks good so far , but I still need to get my 
own project converted before I can give it a try.

John.
-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be


Re: [twsocket] Early web server response

2008-09-22 Thread DZ-Jay
On Sep 21, 2008, at 18:53, Maurizio Lotauro wrote:
 HTTP is stateless, but this has nothing to do with keeping the 
 connection open.
 I don't think that a browser reopen the connection for every part that 
 compose a
 web page.
 And I don't think also that you close and reopen the connection for 
 every file
 you want upload or download to/from an ftp server :-)

I'm sorry but you are confused.  HTTP is not like FTP.  In HTTP 1.1, 
persistent connections were defined but it was a matter of convenience 
and they are not required (RFC #2616, Section 8 uses the term SHOULD 
instead of MUST when discussing the negotiation of persistent 
connections).

As of HTTP 1.1, persistent connections are the default.  But still, 
browsers do open multiple connections otherwise all retrieval would be 
synchronized, and it's not.  They may not create a new connection for 
each resource, but the reuse of the connections is pretty much 
arbitrary.  For the record, prior to 1.1, most servers did not support 
persistent connections, and browsers did in fact had to close and 
reopen the connection for every file they wanted to upload or download. 
  Some servers supported the Keep-Alive mechanism, but--again--it was 
more of a convenience, and could never be expected to be supported by 
either side.

This is why, in my opinion, coercing HTTP as the de facto standard 
protocol for all communications in the Internet (as a lot of people are 
trying to make it) is stupid.  There are better transfer protocols out 
there.  But this is a rant for another day.

 From what I understand now about NTLM (still need
 to learn about it!), it requires the cycle to happen within the same
 session, which counters the RFC, and thus is an exceptional case.

 The basic is the only one that is handled in one step. All others 
 needs a
 negotiation. IIRC the NTLM is anomaly is that it is the server that 
 starts it
 with the first 401 answer.

Again, wrong.  All HTTP authentication uses the same negotiation 
mechanism (even since the days of HTTP 1.0), because they authenticate 
the *request*:

1. The client requests a resource from the server for the very first 
time and it doesn't know it requires authentication.

2. The server responds with an appropriate error code specifying the 
authentication mechanism(s) supported (including Basic and Digest).

(At this point, servers or clients using older versions of the HTTP 
protocol would have closed the connection.)

3. The client re-sends the request with the appropriate credentials and 
the server performs the authorization.

4. On every subsequent request, the client includes the same 
credentials and the server re-authenticates the request.  (Digest has 
some differences, but generally fits this scheme).

Notice that since the protocol is absolutely stateless, the server has 
no idea at any point how many requests have been sent, and it doesn't 
care.  So, the client can remember the specific server's requirements 
and send them in subsequent visits.  And in fact, this is what browsers 
do:  from then on, the authentication can be done in a single request, 
without the error step.

Now, NTLM (yes, finally I read some on it) authenticates the 
*connection*, not the request as the HTTP authentications mechanisms 
do.  This requires that the entire challenge-response cycle be 
performed in a single persistent connection.  As noted in that link you 
sent me, it's actually a bastardization of the protocol:  it's not 
really part of the HTTP 1.1 protocol, but it uses the standard 
mechanisms in a weird way.

Another way that NTLM breaks away from the protocol is that, once the 
connection is authenticated, subsequent requests within the same 
connection need not perform the challenge-response.

Because of its unique nature (damn you, Microsoft!) I'm sure browsers 
treat it as a special case. (I seem to remember having problems with 
Firefox 1.x connecting to my office's intranet site, while IE worked 
fine.  I always knew it had to be some MS extension to the protocol but 
didn't know what.  Now I do.)  Of course, IE will work fine with IIS.  
However, it'll be more interesting to find out how IE copes when 
dealing with Tomcat, which seems to return an error response right 
after the headers.

 In my case the server answers not after the headers but rigth after 
 the client
 has sent the first 8193 byte of the SendStream (that is the size of 
 the THttpCli
 send buffer).

My guess is that, technically, it's after the headers that the server 
reacts, but the first stream buffer (8193 bytes) is already on its way, 
since the client didn't stop to check, so they cross in transit.  It 
could also be that the HttpCli component does not acknowledge the 
response until after if finishes sending the buffer (which makes sense, 
since it's a single-threaded operation), and this causes the delay in 
the receipt of the response.

In any case, I'll see if I can do some experiments with IE and Tomcat 
and let you 

Re: [twsocket] Early web server response [OT]

2008-09-22 Thread Hoby Smith
 DZ-Jay said...

 coercing HTTP as the de facto standard protocol for all communications in
the Internet (as a lot of people are trying to make it) is stupid.  There
are better transfer protocols out there.  

Preach it!  The Commodore 64 implemented better protocols... ;)

 But this is a rant for another day.

I tend to make that rant about five times a day.  But, who's counting? ...
:)

Go DZ!


-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be


Re: [twsocket] Early web server response

2008-09-22 Thread Maurizio Lotauro
Scrive DZ-Jay [EMAIL PROTECTED]:

[...]

I'll answer asap (probably this night).

 In any case, I'll see if I can do some experiments with IE and Tomcat 
 and let you know what I find.

Please wait, I asked to our server admin to prepare a test environment public
available (I need it for myself). Probably it will be ready tomorrow.


Bye, Maurizio.


This mail has been sent using Alpikom webmail system
http://www.alpikom.it

-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be


Re: [twsocket] TSyncSmtpCli and hotmail

2008-09-22 Thread Francois PIETTE
 Is it possible to send outgoing mail through hotmail.com using 
 TSyncSmtpCli?

If hotmail support SMTP, then yes. Otherwise, no.

--
[EMAIL PROTECTED]
The author of the freeware multi-tier middleware MidWare
The author of the freeware Internet Component Suite (ICS)
http://www.overbyte.be

-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be