tall_man has asked for the wisdom of the Perl Monks concerning the following question:

I have been trying to interact with a Frontier:Daemon running on Windows. For test purposes I'm using the simple state_daemon.pl and state-client.pl. I'm running the client on a Linux box and the server on Windows 2000.

The server understands the client and responds to requests like "get_state_name(41)", but the client gets confused by what it gets back. It seems that it can't tell where the header ends, so all my content ends up in Client-Junk.

After extensive tracing with the debugger, I found that the server is sending me lines terminated with "\r\r\n" instead of the expected "\r\n". I attempted a work-around by modifying my_readline in Net::HTTP::Methods like this (on the client side):

#$line =~ s/(\015?\012)\z// || die "Assert"; $line =~ s/(\015*\012)\z// || die "Assert";

That helped a little, but now there is another error about "unclosed token."

Does anyone know of a way to make Frontier::Daemon (or perhaps its parent HTTP::Daemon) behave correctly under Windows? I did a SuperSearch and came up empty-handed. Thanks for your help.

Replies are listed 'Best First'.
Re: Frontier::Daemon over-returns lines
by tall_man (Parson) on Jun 23, 2003 at 20:38 UTC
    I have small program that shows the equivalent problem when writing to a file:
    use strict; use IO::File; my $fh = new IO::File("> qqq.txt"); defined($fh) || die "Cannot open qqq.txt\n"; #binmode($fh); my $CRLF = "\015\012"; print $fh "test",$CRLF; close $fh;
    Without the binmode call, the file is written as "test\r\r\n". Unfortunately, the node A Little History on 0D0A says that binmode can only be used for files, not sockets. For sockets it recommends a $CRLF value like the one given above, but my test program shows that won't work. Windows sees it is supposed to print a "\012", cleverly expands that to "\015\012", and ends up doubling my carriage return.

    In HTTP:Daemon, I find the following line (in the section for HTTP::Daemon::ClientConn):

    my $CRLF = "\015\012"; # "\r\n" is not portable
    Ironically, the given code isn't portable either! I patched it to have "012" instead.

    Unfortunately, my content length still seems to be off this way, and I get the "unclosed token." Does anyone have a better work-around, or a way to set binary mode for sockets? Thanks.

    Update: I have a work-around now on the client side, so I took out the patches on the server side. In Frontier::Client, I did the following:

    my $content = $response->content; # Second-chance attempt for a broken Windows Frontier # service, which puts good results into client-junk. if (!$content) { my $headers = $response->headers; my $cjunk = $headers->{"client-junk"}; if (defined $cjunk) { # Reconstitute the result. $content = join("\n",@$cjunk); } }
    This will work for the small amount of result contents that I need. There is clearly something wrong here that I have to make such a patch, but it will do for now.