home *** CD-ROM | disk | FTP | other *** search
- \ File: http.spf
- \ Author: Nicholas Nemtsev
- \ Description: http operations
- \ Date: 14.Apr.2003 (PAD relation words have been eliminated)
- \ Modified: 22.Sep.2003 (HTTP-RESULT and some bug fixed)
- \ Modified: 17.Feb.2004 + HTTPProxy-Authorization: username:password
- \ Modified: 19.Feb.2004 + port bug fixed (vPort -> vServerPort )
- \ Usage: HTTP-CHANGED: <URL> ( -- ?) - tests Last-Modified field
- \ HTTP-GET: <URL> ( -- a u ior) - downloads resource
- \ HTTP-LM: <URL> ( -- a u ior) - retrieves Last-Modified field
-
- CLASS: HTTPConnection <SUPER SocketLine
- var vServer
- var vServerPort
- var vPath
- var vProxy
- var vProxyPort
- var vFieldList
- var vURL
- var vFH
- var vUserAgent
- var vAddField
- var vProt
- var vResultCode
- var vProxy-Authorization
-
- M: Proxy! S>ZALLOC vProxy ! ;
- M: ProxyPort! vProxyPort ! ;
- M: Server! S>ZALLOC vServer ! ;
- M: ServerPort! vServerPort ! ;
- M: Proxy-Authorization! S>ZALLOC vProxy-Authorization ! ;
-
- M: URL ( a u -- )
- 2DUP S>ZALLOC vURL !
- RE-SAVE
- S" /(http\:\/\/)?([^\/:]*)(\:\d*)?(\/.*)?/i" RE-MATCH
- IF
- [ DEBUG? ]
- [IF]
- ." All=" $0 TYPE CR
- ." Server=" $2 TYPE CR
- ." Port=" $3 TYPE CR
- ." Path=" $4 TYPE CR
- [THEN]
- $1 ?DUP 0= IF DROP S" http://" THEN S>ZALLOC vProt !
- $2 Server!
- $3 ?DUP IF 1 /STRING S>NUM vServerPort ! ELSE DROP THEN
- $4 ?DUP 0= IF DROP S" /" THEN S>ZALLOC vPath !
- THEN
- RE-REST
- ;
-
- CONSTR: init ( a u -- )
- init
- 80 vServerPort !
- 80 vProxyPort !
- URL
- S" Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 4.0)" DROP vUserAgent !
- ;
-
- : free-fields
- [NONAME NodeValue DUP @ ?FREE DUP CELL+ @ ?FREE ?FREE NONAME]
- vFieldList DoList
- vFieldList FreeList ;
-
- DESTR: free free
- vPath @ ?FREE2
- vProxy @ ?FREE
- vServer @ ?FREE
- vURL @ ?FREE
- vUserAgent @ ?FREE2
- vProt @ ?FREE2
- vProxy-Authorization @ ?FREE2
- free-fields ;
-
- M: AddField ( a-name u-name a-val u-val -- ) vFieldList SetProp ;
-
- M: GetField ( a u -- a1 u1) vFieldList GetProp ;
-
- DEBUG?
- [IF]
- : ShowFields
- vFieldList
- BEGIN @ ?DUP WHILE
- DUP
- NodeValue DUP @AZ TYPE ." =" CELL+ @AZ TYPE CR
- REPEAT
- ;
- [THEN]
-
- M: SetAddr
- vProxy @
- IF vProxy @AZ
- vProxyPort @
- ELSE
- vServer @AZ
- vServerPort @
- THEN
- vPort ! Addr!
- ;
-
- M: RequestString ( a1 u1 -- a2 u2)
- 0.
- <# S" HTTP/1.1" HOLDS
- vProxy @ IF \ vURL @AZ
- vPath @AZ HOLDS
- vServerPort @ ?DUP IF S>D #S [CHAR] : HOLD 2DROP THEN
- vServer @AZ HOLDS
- vProt @AZ HOLDS
- ELSE vPath @AZ HOLDS THEN
- BL HOLD
- 2SWAP HOLDS #>
- [ DEBUG? ] [IF] 2DUP TYPE CR [THEN]
- ;
-
- M: SendOption ( a1 a2 u2 -- )
- ROT @ ?DUP
- IF ASCIIZ> <# HOLDS S" : " HOLDS HOLDS 0. #> WriteLine
- ELSE 2DROP THEN ;
-
- M: SendRequest ( a u -- )
- SetAddr
- Create Connect
- RequestString WriteLine
- vUserAgent S" User-Agent" SendOption
- \ Wget/1.8" WriteLine
- vServer S" Host" SendOption
- S" Accept: */*" WriteLine
- vProxy-Authorization S" Proxy-Authorization" SendOption
- vAddField @ ?DUP IF ASCIIZ> WriteLine THEN
- \ S" Connection: Keep-Alive" WriteLine
- \ S" Pragma: no-cache"
- WriteCRLF ;
-
- M: GetHeader ( -- )
- free-fields
- BEGIN ReadLine ?DUP WHILE
- \ ." --" 2DUP TYPE CR
- 2DUP S" /(.*): (.*)/" RE-MATCH
- IF $1 $2 AddField THEN
- S" /HTTP\/\d\.\d (\d+) /" RE-MATCH
- IF $1 S>NUM vResultCode ! THEN
- REPEAT
- DROP
- ;
-
- M: HEAD ( -- ior)
- [NONAME
- S" HEAD" SendRequest
- GetHeader
- Close
- NONAME] CATCH
- [ DEBUG? ] [IF] ShowFields [THEN]
- ;
-
- M: GetBody { \ buf len-buf cont-len len -- }
- S" Content-Length" GetField S>NUM TO cont-len
- 512 TO len-buf
- len-buf ALLOCATE THROW TO buf
- LINE_BUFF_SIZE ReadFromPending DUP TO len
- vFH @ WRITE-FILE THROW
- BEGIN
- len cont-len < cont-len 0= OR
- IF
- buf len-buf Sock ReadSocket DUP -1002 =
- IF 2DROP FALSE ELSE THROW THEN
- ?DUP
- ELSE
- FALSE
- THEN
- WHILE
- DUP AT len +!
- buf SWAP \ 2DUP TYPE CR
- vFH @ WRITE-FILE THROW
- REPEAT
- buf FREE THROW
- ;
-
- M: GET ( a u -- ior)
- R/W MAKE-FILE THROW vFH !
- [NONAME
- S" GET" SendRequest
- GetHeader
- GetBody
- Close
- NONAME] CATCH
- vFH @ CLOSE-FILE DROP
- ;
-
- M: Last-Modified ( -- a u ior)
- HEAD ?DUP
- IF S" " ROT
- ELSE
- S" Last-Modified" GetField ?DUP 0=
- IF DROP S" Content-Length" GetField THEN
- 0
- THEN
- ;
-
- ;CLASS
-
- USER-VALUE http
- USER-VALUE HTTP-RESULT
- VARIABLE HTTPProxy
- VARIABLE HTTPProxyPort 3128 HTTPProxyPort !
- VARIABLE HTTPProxy-Authorization
- VARIABLE HTTPProxy-Authorization-Type
-
- : HTTPProxy: get-string S>ZALLOC HTTPProxy ! ;
- : HTTPProxyPort: get-number HTTPProxyPort ! ;
- : HTTPProxy-Authorization:
- get-string
- HTTPProxy-Authorization-Type @
- CASE
- 0 OF
- DUP 2* ALLOCATE THROW >R
- R@ 0 TO 64offset base64
- S" Basic %1 esPICKS%" EVAL-SUBST
- [ DEBUG? ]
- [IF]
- ." HTTPProxy-Authorization: " 2DUP TYPE CR
- [THEN]
- R> FREE DROP
- ENDOF
- ENDCASE
- S>ZALLOC HTTPProxy-Authorization !
- ;
-
- WITH HTTPConnection
- : new-http
- HTTPConnection NEW TO http
- HTTPProxy @ ?DUP
- IF ASCIIZ> http => Proxy! HTTPProxyPort @ http => ProxyPort!
- HTTPProxy-Authorization @ ?DUP
- IF ASCIIZ> http => Proxy-Authorization! THEN
- THEN ;
-
- : HTTP-LM ( a u -- a u ior)
- new-http
- http => Last-Modified
- ?DUP 0= IF S>TEMP 0 THEN
- http => vResultCode @ TO HTTP-RESULT
- http => SELF DELETE
- ;
-
-
- : HTTP-GET { a u \ tmpname -- a u ior }
- a u new-http
- TempFile S>ZALLOC TO tmpname
- tmpname ASCIIZ> http => GET ?DUP 0=
- IF
- tmpname ASCIIZ> FILE 0
- ELSE
- S" " ROT
- THEN
- http => vResultCode @ TO HTTP-RESULT
- http DELETE
- tmpname ASCIIZ> DELETE-FILE DROP
- tmpname ?FREE
- ;
-
- ENDWITH
-
- VARIABLE HTTP-LIST \ list of URL with corresponding Last-Modified
- VARIABLE HTTP-SEM
- : htime.txt S" etc\htime.txt" ;
-
- : ?load-htime { \ len buf1 buf2 f -- }
- HTTP-SEM GET
- HTTP-LIST @ 0=
- IF
- htime.txt R/O OPEN-FILE-SHARED DUP 2 <>
- IF
- THROW TO f
- 1024 TO len
- len CELL+ ALLOCATE THROW TO buf1
- len CELL+ ALLOCATE THROW TO buf2
- BEGIN buf1 len f READ-LINE THROW WHILE
- buf1 SWAP
- buf2 len f READ-LINE THROW DROP
- buf2 SWAP HTTP-LIST GLOBAL SetProp LOCAL
- REPEAT
- DROP
- f CLOSE-FILE DROP
- buf1 ?FREE
- buf2 ?FREE
- ELSE 2DROP THEN
- THEN
- HTTP-SEM RELEASE
- ;
- : htime-line htime.txt FAPPEND CRLF htime.txt FAPPEND ;
- : write-htime
- HTTP-SEM GET
- HTTP-LIST @
- IF
- htime.txt R/W MAKE-FILE THROW CLOSE-FILE DROP
- [NONAME
- NodeValue DUP @AZ htime-line
- CELL+ @AZ htime-line
- NONAME] HTTP-LIST DoList
- THEN
- HTTP-SEM RELEASE
- ;
-
- : HTTP-CHANGED { a u -- ? }
- ?load-htime
- a u HTTP-LM 0=
- IF
- 2DUP a u HTTP-LIST GetProp COMPARE
- IF
- HTTP-SEM GET
- a u 2OVER HTTP-LIST GLOBAL SetProp LOCAL DROP ?FREE
- HTTP-SEM RELEASE
- write-htime
- TRUE
- ELSE
- 2DROP FALSE
- THEN
- ELSE 2DROP FALSE THEN
- ;
-
- C" eval-string," FIND NIP
- [IF]
- : HTTP-CHANGED: eval-string, POSTPONE HTTP-CHANGED ; IMMEDIATE
- : HTTP-LM: eval-string, POSTPONE HTTP-LM ; IMMEDIATE
- : HTTP-GET: eval-string, POSTPONE HTTP-GET ; IMMEDIATE
- [THEN]
-