      subroutine http.sub(cmd, url, hdrs, post.data, res, r.hdrs, r.data, err)
*
*
*
*
*
*
*
*
*
$catalog local

      equate short.timeout to   30000 ;* 30 seconds
      equate long.timeout  to  600000 ;* 10 minutes
      equate max.hdr.len   to  500000 ;* 500Kbytes
      equate min.rd.wait   to  120000 ;* 2 minutes
      equate min.rd.rate   to       1 ;* 1 bytes/ms

      crlf = char(13) : char(10)

      r.hdrs = ''
      r.data = ''
      err = ''
      eof = 0

      if downcase(url[1,7]) <> 'http://' then
         err = 'Invalid url.'
         return
      end

      s = url[8,999999999]
      t = index(s,'/',1)
      if t then
         host = s[1,t-1]
         req = '/' : s[t+1,999999999]
      end else
         host = s
         req = '/'
      end

      cmd = upcase(cmd)
      begin case
         case cmd = 'GET'
         case cmd = 'HEAD'
         case cmd = 'POST'
         case 1
            err = 'Invalid cmd.'
            return
      end case
         
      if not(index(host,':',1)) then host = host : ':80'

      call sock.connect(host,'',sockfd,err)

      if err <> '' then return

      obuf = 'GET ' : req : ' HTTP/1.0'
      if not(index(downcase(hdrs),'user-agent:',1)) then
         obuf<-1> = 'User-Agent: OpenQM 1.0'
      end
      if not(index(downcase(hdrs),'server:',1)) then
         obuf<-1> = 'Server: ' : host
      end

      i1 = dcount(hdrs,@am)
      for i = 1 to i1
         obuf<-1> = hdrs<i>
      next i

      if cmd = 'POST' then
         obuf<-1> = 'Content-Length: ' : len(post.data)
      end

      obuf = change(obuf,@vm,crlf) : crlf : crlf

      if cmd = 'POST' then
         obuf = obuf : post.data
      end

      call sock.write(sockfd,obuf,short.timeout,long.timeout,err)

      if err <> '' then return

      * Get response header

      ibuf = ''
      call sock.read(sockfd,max.hdr.len,short.timeout,long.timeout,crlf:crlf,ibuf,err)

      if err = 'EOF' then
         eof = 1
         err = ''
      end

      if err <> '' then return

      loop while ibuf[1,2] = crlf do
         ibuf = ibuf[3,999999999]
      repeat

      t = index(ibuf,crlf:crlf,1)

      if not(t) then
         call csub.close(sockfd,'')
         err = 'HTTP header not returned.'
         return
      end

      r.hdrs = ibuf[1,t-1]
      r.data = ibuf[t+4,999999999]

      r.hdrs = change(r.hdrs,crlf,@vm)

      res = r.hdrs<1>
      r.hdrs = delete(r.hdrs,1,1,0)
      data.len = 0
      i1 = dcount(r.hdrs,@vm)
      for i = 1 to i1
         if field(downcase(r.hdrs<1,i>),':',1) = 'content-length' then
            data.len = trim(field(r.hdrs<1,i>,':',2))
            exit
         end
      next i

      if len(r.data) < data.len then
         call sock.read(sockfd,data.len,short.timeout,min.rd.wait+(data.len*min.rd.rate),'',r.data,err)
         if err = 'EOF' then
            eof = 1
            err = ''
         end
      end

      call csub.close(sockfd,'')

      return
   end
