mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Mar 2006
Posts: 6
Z
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
Z
Joined: Mar 2006
Posts: 6
Code:
alias getstats set %getstats $1 | sockclose stats1 | sockopen stats1 xwis.net 80
on *:sockopen:stats1:sockwrite stats1 $+(GET /xcl/?pname=,%getstats HTTP/1.1,$crlf,Host: xwis.net,$crlf,$crlf)
on *:sockread:stats1:{
  var %var 
  sockread %var
  echo -a $sockname >> %var
}
on *:sockclose:stats:echo -a CLOSED!


When I use /getstats continual, it echoes me this:

Quote:
stats1 >> HTTP/1.1 200 OK
stats1 >> Date: Sat, 03 Jun 2006 17:11:07 GMT
stats1 >> Server: Apache/2.0.55 (Debian) PHP/5.1.2-1+b1 mod_ssl/2.0.55 OpenSSL/0.9.8a
stats1 >> X-Powered-By: PHP/5.1.2-1+b1
stats1 >> refresh: 300
stats1 >> Vary: Accept-Encoding
stats1 >> Content-Length: 281
stats1 >> Content-Type: text/html
stats1 >>
stats1 >> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
stats1 >> <script type="text/javascript" src="xcl.js"></script>
stats1 >> <script type="text/javascript">page_top(0);


There's a line missing now. You can see it by checking thepage source. The line would at this time be "page_search(0);t0(new Array(17,1,3519,'continual',17,0,499,499,1149306577,1,0), 1);page_bottom(1149354870);</script>".

If I quickly hit $sock(stats).rq and tab before the socket gets closed, it says "116", which is the length of the missing line. Now my guess would be that the sockread event doesn't get triggered anymore. That could be because of virus scanners blocking possible dangerous content.. but that's not it. If I run ethereal at the same time it does show up.

If I use &bvars I do get the full content, but I'd like to use regular variables for this. Anyone got any ideas? BTW: it's not in the "missing" headers, and on my mums pc it does work, and on some other guy's pc's it doesn't work either.

Joined: Dec 2002
Posts: 580
N
Fjord artisan
Offline
Fjord artisan
N
Joined: Dec 2002
Posts: 580
Not sure if this will fix your problem, but I do something simular (using bvars) to download files with sockets...

Try this...
Code:
on *:sockread:stats1:{
  var %var 
  :reread
  sockread %var
  if (%var) {
    echo -a $sockname &gt;&gt; %var
    goto reread
  }
}


NaquadaBomb
www.mirc-dll.com
Joined: Oct 2005
Posts: 1,741
G
Hoopy frood
Offline
Hoopy frood
G
Joined: Oct 2005
Posts: 1,741
Try using HTTP/1.0 instead of HTTP/1.1


-genius_at_work

Joined: Mar 2006
Posts: 6
Z
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
Z
Joined: Mar 2006
Posts: 6
I'm quite sure I already posted.. but there's no comment.

Using HTTP/1.0 didn't work either, sorry I didn't say that in the first comment. I do have it solved: using the -f switch in the sockread command and looping until $sockbr reaches zero did the trick. Using only the -f switch, or just what Nequada said has no different effect, only when used in combination. Now I do have it solved, I'd still like to know why I have to use this combination. Any logical explanations (not "I guess..."?

Joined: Mar 2006
Posts: 6
Z
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
Z
Joined: Mar 2006
Posts: 6
It seems this bug is not completely mIRC related. Using PHP I do get errors when sockreading in normal mode, but not in binary mode (PHP_NORMAL_READ vs PHP_BINARY_READ). I tried reinstalling winsock but that didn't help. If anyone can tell me what to google on, or even better, how to fix it, let me know smile

Joined: Apr 2004
Posts: 871
Sat Offline
Hoopy frood
Offline
Hoopy frood
Joined: Apr 2004
Posts: 871
The reason is much simpler than that. The last line of the page is not terminated by a newline, and /sockread without -f only reads newline-terminated lines. Using /sockread -f you can read data that isn't terminated by a newline, but "on sockread" only triggers when there's a newline-terminated line available [1] which is why just adding -f to your original code doesn't work, and why adding a loop does work (as it forces mIRC to read out the rest, newline or not).

However, it's dangerous to use /sockread -f like that, because it could happen that for example one-and-a-half line arrives first, and the second half of the second line later (on the TCP level!) in which case you will read the whole first line, then the first half of the second line, and later the second half of the second line, and see them as three lines instead of two! In this case it's not likely to happen, but better practice is to instead use a trick: only use /sockread -f to read the last line from the on sockclose event. This way you will only read half a line if there really is half a line and nothing more, because on sockclose obviously only triggers when the connection is closed.

A slight complication in this case is that your use of HTTP/1.1 will automatically keep the connection open, so "on sockclose" will not trigger anytime soon. Changing the request to use "HTTP/1.0" is a simple fix here, although you could also add the "Connection: close" header to the HTTP/1.1 request. All in all this gives the following code (note you had the socket name wrong in the "on sockclose" event originally):

Code:
alias getstats set %getstats $1 | sockclose stats1 | sockopen stats1 xwis.net 80
on *:sockopen:stats1:sockwrite stats1 $+(GET /xcl/?pname=,%getstats HTTP/1.0,$crlf,Host: xwis.net,$crlf,$crlf)
on *:sockread:stats1:{
  var %var 
  sockread %var
  echo -a $sockname &gt;&gt; %var
}
on *:sockclose:stats1:{
  var %var 
  sockread -f %var
  echo -a $sockname &gt;&gt; %var
  echo -a CLOSED!
}

Note that you should also add normal error checking on $sockerr and $sockbr etc. But this should work already.

However, if you have any control over the webpage you're pulling the data from, it's easier to just add a newline after the last line...

[1] a somewhat simplified version of the story here


Saturn, QuakeNet staff

Link Copied to Clipboard