home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxgeturl.zip / rxgeturl.cmd
OS/2 REXX Batch file  |  2002-04-09  |  8KB  |  167 lines

  1. /* REXX: get http document (result incl. http headers to stdout)  */
  2. /* v0.2: optional authorization@www.test instead of www.test for  */
  3. /*       "Authorization:" header, use "Connection: Close" header, */
  4. /*       avoid chunked data by specifying HTTP/1.0 instead of 1.1 */
  5.  
  6.    signal on novalue  name TRAP  ;  signal on syntax name TRAP
  7.    signal on failure  name TRAP  ;  signal on halt   name TRAP
  8.  
  9.    parse arg TEXT
  10.    select
  11.       when arg()         > 2 then  exit TRAP( 'too many arguments' )
  12.       when arg()         = 2 then  parse arg PEERNAME ,     TEXT
  13.       when words( TEXT ) > 2 then  exit TRAP( 'too many arguments' )
  14.       when words( TEXT ) = 2 then  parse arg PEERNAME       TEXT .
  15.       when words( TEXT ) = 1 then  parse arg PEERNAME '/'   TEXT .
  16.       otherwise                    exit HELP()
  17.    end
  18.  
  19.    SOCK = -1   ;  N = 'SockLoadFuncs'
  20.    if RxFuncQuery( N ) then            /* here FAIL throws a TRAP */
  21.       if RxFuncAdd( N, 'RXSOCK', N ) then
  22.          return FAIL( N 'in RXSOCK.DLL not found' )
  23.    call SockLoadFuncs 'N'
  24.  
  25.    parse var PEERNAME PASSWORD '@' PEERNAME
  26.    if PEERNAME = '' then parse var PASSWORD PEERNAME PASSWORD
  27.    if SockGetHostByName( PEERNAME, 'PEER.1' ) = 0
  28.       then return FAIL( 'unknown host' PEERNAME )
  29.  
  30.    PEER.1FAMILY   = 'AF_INET' ;  CRLF = x2c( 0D0A )
  31.    PEER.1PORT     = 80
  32.  
  33.    TEXT = 'GET /'       || TEXT 'HTTP/1.0'
  34.    TEXT = TEXT || CRLF  || 'Host:' || PEERNAME
  35.    if PASSWORD <> '' then do
  36.       PASSWORD = MIME( PASSWORD )
  37.       TEXT = TEXT || CRLF  || 'Authorization: Basic' PASSWORD
  38.    end
  39.    TEXT = TEXT || CRLF  || 'Pragma: no-cache'
  40.    TEXT = TEXT || CRLF  || 'Connection: close'
  41.    TEXT = TEXT || CRLF  || 'User-Agent: RxGetUrl.cmd/0.2'
  42.    TEXT = TEXT || CRLF  || CRLF
  43.  
  44.    SOCK = SockSocket( 'AF_INET', 'SOCK_STREAM', 'IPPROTO_TCP' )
  45.    if SOCK = -1 then return FAIL( 'SockSocket() =' SOCK )
  46.  
  47.    signal on novalue  name SOCK  ;  signal on syntax name SOCK
  48.    signal on failure  name SOCK  ;  signal on halt   name SOCK
  49.  
  50.    if SockConnect( SOCK, 'PEER.1' ) <> 0 then
  51.       return FAIL( 'SockConnect' )
  52.    if SockSend( SOCK, TEXT ) = -1 then
  53.       return FAIL( 'SockSend' )
  54.    if SockShutDown( SOCK, 1 ) <> 0 then
  55.       return FAIL( 'SockShutDown' )
  56.  
  57.    TEXT = ''
  58.    do until N = 0
  59.       N = SockRecv( SOCK, 'MORE', 256 )
  60.       if N = -1 then return FAIL( 'SockRecv' )
  61.       TEXT = TEXT || left( MORE, N )
  62.    end
  63.  
  64.    if SockClose( SOCK ) <> 0 then return FAIL( 'SockClose' )
  65.  
  66.    signal on novalue  name TRAP  ;  signal on syntax name TRAP
  67.    signal on failure  name TRAP  ;  signal on halt   name TRAP
  68.  
  69.    say TEXT ;  exit 0
  70.  
  71. MIME: procedure                  /* encode authorization string:  */
  72.    SRC = x2b( c2x( arg( 1 )))
  73.    ADD = ''
  74.    DST =        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef'
  75.    DST = DST || 'ghijklmnopqrstuvwxyz0123456789+/'
  76.    do N = 0 until DST = '' ;  parse var DST C.N 2 DST ;  end N
  77.    do N = 1 to (( length( SRC ) // 24 ) / 4 ) // 3
  78.       ADD = ADD || '='  ;  SRC = SRC || '00'
  79.    end N
  80.    do while SRC <> ''
  81.       parse var SRC N 7 SRC
  82.       N = x2d( b2x( N ))
  83.       DST = DST || C.N
  84.    end
  85.    return DST || ADD
  86.  
  87. HELP: procedure                  /* show usage message and return */
  88.    parse source . . N
  89.    N = substr( N, 1 + lastpos( '\', N ))
  90.    N = substr( N, 1 + lastpos( '/', N ))
  91.    NN = ' e.g.:' N 'www.xyzzy.claranet.de index.html'
  92.    NN = 'usage:' N 'host file' x2c( 0D0A ) || NN
  93.    say NN   ;  return NN         /* caller can show NN in PM win. */
  94.  
  95. FAIL: procedure expose SOCK      /* show a socket error on stderr */
  96.    NN = arg( 1 ) '(error' max( 0, SockSock_errno() - 10000 ) || ')'
  97.    call SockPSock_errno NN       /* REXX handles missing function */
  98.    call SockClose SOCK           /* as syntax TRAP exiting anyway */
  99.    return NN                     /* caller can show NN in PM win. */
  100.  
  101. /* -------------------------------------------------------------- */
  102.  
  103. SOCK:                            /* close socket and handle TRAP: */
  104.    call SockClose SOCK
  105.    if result <> 0 then call SockPSock_errno 'SockClose() =' result
  106.  
  107. TRAP:                            /* select REXX exception handler */
  108.    call trace 'O' ;  trace N           /* don't trace interactive */
  109.    parse source TRAP                   /* source on separate line */
  110.    TRAP = x2c( 0D ) || right( '+++', 10 ) TRAP || x2c( 0D0A )
  111.    TRAP = TRAP || right( '+++', 10 )   /* = standard trace prefix */
  112.    TRAP = TRAP condition( 'c' ) 'trap:' condition( 'd' )
  113.    select
  114.       when wordpos( condition( 'c' ), 'ERROR FAILURE' ) > 0 then do
  115.          if condition( 'd' ) > ''      /* need an additional line */
  116.             then TRAP = TRAP || x2c( 0D0A ) || right( '+++', 10 )
  117.          TRAP = TRAP '(RC' rc || ')'   /* any system error codes  */
  118.          if condition( 'c' ) = 'FAILURE' then rc = -3
  119.       end
  120.       when wordpos( condition( 'c' ), 'HALT SYNTAX'   ) > 0 then do
  121.          if condition( 'c' ) = 'HALT' then rc = 4
  122.          if condition( 'd' ) > '' & condition( 'd' ) <> rc then do
  123.             if condition( 'd' ) <> errortext( rc ) then do
  124.                TRAP = TRAP || x2c( 0D0A ) || right( '+++', 10 )
  125.                TRAP = TRAP errortext( rc )
  126.             end                        /* future condition( 'd' ) */
  127.          end                           /* may use errortext( rc ) */
  128.          else  TRAP = TRAP errortext( rc )
  129.          rc = -rc                      /* rc < 0: REXX error code */
  130.       end
  131.       when condition( 'c' ) = 'NOVALUE'  then rc = -2 /* dubious  */
  132.       when condition( 'c' ) = 'NOTREADY' then rc = -1 /* dubious  */
  133.       otherwise                        /* force non-zero whole rc */
  134.          if datatype( value( 'RC' ), 'W' ) = 0 then rc = 1
  135.          if condition() = '' then TRAP = TRAP arg( 1 )
  136.    end                                 /* direct: TRAP( message ) */
  137.  
  138.    TRAP = TRAP || x2c( 0D0A ) || format( sigl, 6 )
  139.    signal on syntax name TRAP.SIGL     /* throw syntax error 3... */
  140.    if 0 < sigl & sigl <= sourceline()  /* if no handle for source */
  141.       then TRAP = TRAP '*-*' strip( sourceline( sigl ))
  142.       else TRAP = TRAP '+++ (source line unavailable)'
  143. TRAP.SIGL:                             /* ...catch syntax error 3 */
  144.    if abbrev( right( TRAP, 2 + 6 ), x2c( 0D0A )) then do
  145.       TRAP = TRAP '+++ (source line unreadable)'   ;  rc = -rc
  146.    end
  147.    select
  148.       when 0 then do                   /* in pipes STDERR: output */
  149.          parse version TRAP.REXX . .   /* REXX/Personal: \dev\con */
  150.          signal on syntax name TRAP.FAIL
  151.          if TRAP.REXX = 'REXXSAA'      /* fails if no more handle */
  152.             then call lineout 'STDERR'  , TRAP
  153.             else call lineout '\dev\con', TRAP
  154.       end
  155.       when 1 then do                   /* OS/2 PM: RxMessageBox() */
  156.          signal on syntax name TRAP.FAIL
  157.          call RxMessageBox ,           /* fails if not in PMREXX  */
  158.             translate( TRAP, ' ', x2c( 0D )), , 'CANCEL', 'WARNING'
  159.       end                              /* replace any CR by blank */
  160.       otherwise   say TRAP ; trace ?L  /* interactive Label trace */
  161.    end
  162.  
  163.    if condition() = 'SIGNAL' then signal TRAP.EXIT
  164. TRAP.CALL:  return rc                  /* continue after CALL ON  */
  165. TRAP.FAIL:  say TRAP ;  rc = 0 - rc    /* force TRAP error output */
  166. TRAP.EXIT:  exit   rc                  /* exit for any SIGNAL ON  */
  167.