HTTP/MIRC Scripting Language

From Rosetta Code
HTTP/MIRC Scripting Language is part of HTTP. You may find other members of HTTP at Category:HTTP.

A simple implementation of the HTTP protocol in MIRC Scripting Language. The 'on SOCKREAD' event is structured that way so that it can be re-entered when more data arrives, without losing any information.
<lang mirc>; /wget http://www.example.com/somefile.txt alias wget {

 var %url = $1-
 var %id = wget. $+ $ctime
 ; A simple regular expression to parse the url:
 var %re = ^http://([^\s/]+)(.*)
 if ($regex(wget,%url,%re) !isnum 1-) {
   echo -ti2a * wget: Invalid url: %url
   return
 }
 var %hostport = $regml(wget,1)
 var %path = $regml(wget,2)
 ; Split on ":"
 var %host = $gettok(%hostport,1,58)
 var %port = $gettok(%hostport,2,58)
 ; Default values
 if (%port == $null) {
   %port = 80
 }
 if (%path == $null) {
   %path = /
 }
 ; Open a socket to the server, and mark it with some
 ; information we will need later
 sockopen %id %host %port
 sockmark %id %hostport %path

}

on *:SOCKOPEN:wget.*:{

 var %id = $sockname
 if ($sockerr) {
   echo -ti2a * wget: Error while connecting: $sock($sockname).wserr $&
     $sock($sockname).wsmsg
   sockclose %id
   halt
 }
 ; Take out the hostname and path which the socket has been marked with
 var %mark = $sock(%id).mark
 var %hostport = $gettok(%mark,1,32)
 var %path = $gettok(%mark,2-,32)
 ; Update the mark with a state name. (See below)
 sockmark %id statusline
 ; Send the request
 var %w = sockwrite -tn %id
 %w GET %path HTTP/1.0
 %w Host: %hostport
 %w Connection: Close
 %w $crlf

}

on *:SOCKREAD:wget.*:{

 var %id = $sockname
 if ($sockerr) {
   echo -ti2a * wget: Error while receiving: $sock($sockname).wserr $sock($sockname).wsmsg
   sockclose %id
   halt
 }
 ; Look at the current state
 var %state = $sock(%id).mark
 ; Read the first line
 var %line
 sockread %line
 ; Loop while more data is coming in
 while ($sockbr) {
   if (%state == statusline) {
     ; STATUSLINE: This state is the initial one.
     ; Examine the status line and take an appropriate action
     var %version = $gettok(%line,1,32)
     var %code = $gettok(%line,2,32)
     var %reason = $gettok(%line,3-,32)
     if (2?? iswm %code) {
       ; 2xx codes indicate it went ok
       %state = headers
       sockmark %id %state
     }
     elseif (3?? iswm %code) {
       ; 3xx codes indicate redirection
       %state = redirect
       sockmark %id %state
     }
     else {
       ; but anything else is treated as an error
       echo -ti2a * wget: Server error: %line
       sockclose %id
       halt
     }
   }
   elseif (%state == redirect) {
     ; REDIRECT: This state is entered when a 3xx status code is received.
     ; Find the 'Location' header, and issue a new request.
     if ($len(%line) == 0) {
       ; An empty line indicate the end of the headers
       echo -ti2a * wget: Server error: Got 3xx status code, but nowhere to redirect.
       sockclose %id
       halt
     }
     else {
       var %header = $gettok(%line,1,58)
       var %value = $gettok(%line,2-,58)
       if (%header == Location) {
         ; 'Location' header found. Issue a new request.
         wget %value
         sockclose %id
         halt
       }
     }
   }
   elseif (%state == headers) {
     ; HEADERS: This state is entered after the status line has been examined.
     ; Examine the headers, and look for a blank line.
     if ($len(%line) == 0) {
       ; An empty line indicate the end of the headers
       %state = data
       sockmark %id %state
     }
     else {
       var %header = $gettok(%line,1,58)
       var %value = $gettok(%line,2-,58)
       ; Do something with the headers
     }
   }
   elseif (%state == data) {
     ; DATA: This state is the final one.
     ; Read and display everything received
     echo -a %line
   }
   sockread %line
 }

}</lang>