Debug and avoid periodic REBOL2 errors that try to [] not (?) Catch?

Apparently, an unattractive bug when using Rebol/Core (278-3-1) to create some kind of web server for serving static text containing a redirect link to a new service location.

The exact location of the error is presented in the example code written by Carl Sassenrath himself, back in 2006, so I'm a little puzzled, after all these years there may be an undetected error.

Three of these scripts work for me at the same time, controlling three separate ports. Essentially, the script works as it should ... when you re-access it with multiple browsers at the same time (on all parallel scripts), it looks pretty stable ... but one by one they fail. Sometimes after 2 minutes, sometimes after 20 minutes - after adding print applications, sometimes even after 60 minutes, but in the end they will not work as follows:

** script Error: out of range or past end
** Where: forever
** Near: not empty? request: first http port

I tried to wrap almost every part of the program loop in try [] [exception], but the error still occurs. Unfortunately, my search for fu seems weak at this time of the year, as I did not find anything that could explain the problem.

The code is a shortened version of Carl Sassenrath A tiny web server slightly modified to bind to a specific IP address and to release HTML instead of downloading files:

 REBOL [title: "TestMovedServer"] AppName: "Test" NewSite: "http://test.myserver.org" listen-port: open/lines tcp://:81 browse http://10.100.44.6? buffer: make string! 1024 ; will auto-expand if needed forever [ http-port: first wait listen-port clear buffer while [not empty? request: first http-port][ print request repend buffer [request newline] print "----------" ] repend buffer ["Address: " http-port/host newline] print buffer Location: "" mime: "text/html" parse buffer ["get" ["http" | "/ " | copy Location to " "]] data: rejoin [{ <HTML><HEAD><TITLE>Site Relocated</TITLE></HEAD> <BODY><CENTER><BR><BR><BR><BR><BR><BR> <H1>} AppName { have moved to <A HREF="} NewSite {">} NewSite {</A></H1> <BR><BR><BR>Please update the link you came from. <BR><BR><BR><BR><BR><A HREF="} NewSite Location {">(Continue directly to the requested page)</A> </CENTER></BODY></HTML> }] insert data rejoin ["HTTP/1.0 200 OK^/Content-type: " mime "^/^/"] write-io http-port data length? data close http-port print "============" ] 

I look forward to what you guys will make of it!

+6
source share
2 answers

When you try to read from a closed connection, an error message appears. This seems to work.

 n: 0 forever [ http-port: first wait listen-port clear buffer if attempt [all [request: first http-port not empty? request]] [ until [ print request repend buffer [request newline] print "----------" any [not request: first http-port empty? request] ] repend buffer ["Address: " http-port/host newline] print buffer Location: "" mime: "text/html" parse buffer ["get" ["http" | "/ " | copy Location to " "]] data: rejoin [{ <HTML><HEAD><TITLE>Site Relocated</TITLE></HEAD> <BODY><CENTER><BR><BR><BR><BR><BR><BR> <H1>} AppName n: n + 1 { has moved to <A HREF="} NewSite {">} NewSite {</A></H1> <BR><BR><BR>Please update the link you came from. <BR><BR><BR><BR><BR><A HREF="} NewSite Location {">(Continue directly to the requested page)</A> </CENTER></BODY></HTML> }] insert data rejoin ["HTTP/1.0 200 OK^/Content-type: " mime "^/^/"] write-io http-port data length? data ] attempt [close http-port] print "============" ] 
+3
source

Let's see the documentation on empty? Short description:

Returns TRUE if the series is in the tail. Using:

is it empty? Series Arguments:

series - The argument to the series. (should be: serial port bit)

Is it so empty? requires a serial, port, or bit or string argument. Your variable ( request ) receives any of them while there is a connection to the port. is it empty? can subsequently determine if it is in the tail of the variable. When the connection is closed / aborted, your variable does not receive anything, but there is an error accessing the port. The error has no tail. is it empty? gets confused and the failure occurs with an error.

replaced sqlab empty? with an attempt

 if attempt [all [request: first http-port not empty? request]] 

The ATTEMPT function is a shortcut for frequent cases:

 error? try [block] 

with everything it protects against error, and also not. ATTEMPT returns the result of the block if an error did not occur. If an error occurs, returns NONE. also with before and

 any [not request: first http-port empty? request] 

he protects from both.

Therefore, its code works.

+1
source

All Articles