httphostname=DISKBUF+0x400
dnsbuf=DISKBUF+0x0600
IPPROTO_TCP EQU 6
IPPROTO_UDP EQU 17
AF_UNSPEC EQU 0
AF_INET EQU 2
AF_INET6 EQU 23
SOCK_STREAM EQU 0x01 ;tcp/ip
SOCK_DGRAM EQU 0x03 ;udp/ip
SHUT_RDWR EQU 2
ERR_INTR EQU 4
ERR_NFILE EQU 23
ERR_EAGAIN EQU 35 ;/* Try again */
ERR_ALREADY EQU 37
ERR_NOTSOCK EQU 38
ERR_EMSGSIZE EQU 40 ;/* Message too long */
ERR_PROTOTYPE EQU 41
ERR_AFNOSUPPORT EQU 47
ERR_HOSTUNREACH EQU 65
ERR_CONNRESET EQU 54
ERR_NOTCONN EQU 57
proxserv
db "nedoos.ru/p/",0
openstream_http
;de=filename (without "http://"), slash always presents
;out: A!=0 => error
ex de,hl
openstream_http_hl
push hl
ld de,httphostname
ld a,(curprotocol)
cp 3
jr nz,nonhttps
ld hl,proxserv
call strcopy
dec de
nonhttps
pop hl
;push de
call strcopy ;hl->de
ld hl,80*256 ;BIG ENDIAN
ld a,(curprotocol)
cp 2
jr nz,$+4 ;1/3=http
ld h,70 ;2=gopher
ld (curport),hl
ld hl,httphostname ;pop hl
;call findslash
openstream_http_findslash0
ld a,(hl)
cp ':'
jr z,openstream_http_setport
cp '/'
jr z,openstream_http_slash
or a
jr z,openstream_http_slash
inc hl
jr openstream_http_findslash0
openstream_http_setport
ld (hl),0 ;end of httphostname
;decode port
ld de,0 ;oldport
openstream_http_decodeport0
inc hl
ld a,(hl)
sub '0'
cp 10
jr nc,openstream_http_decodeportq
push hl
ld h,d
ld l,e
add hl,hl
add hl,hl
add hl,de
add hl,hl ;hl=oldport*10
add a,l
ld e,a
adc a,h
sub e
ld d,a ;de=port
pop hl
jr openstream_http_decodeport0
openstream_http_decodeportq
;de=port
ld a,d
ld d,e
ld e,a
ld (curport),de ;BIG ENDIAN
;hl=delimiter after ser.ver:NNN
openstream_http_slash
;hl=at delimiter after hostname and maybe port
xor a
cp (hl)
ld (hl),a ;end of httphostname
jr z,$+3
inc hl ;after delimiter
push hl ;filename after ser.ver/
;httphostname=server name (filename before slash, not including slash)
;top of stack=filename after slash (after ser.ver/)
call dns_resolver
ld a,l
or h
jp z,CONNECTIONERROR
ld de,host_ia+3
ld bc,4
ldir
;create socket:
ld de,SOCK_STREAM+(AF_INET<<8)
OS_NETSOCKET
ld a,l
or a
jp m,CONNECTIONERROR;?C_EXIT
ld (soc1),a
LD DE,host_ia
OS_NETCONNECT
ld a,l ;DimkaM 12.03.2019
or a
jp p,connect_ok
createsoc_err
ld a,(soc1)
ld e,0
OS_NETSHUTDOWN
jp CONNECTIONERROR
connect_ok
;form GET message in DISKBUF (will be deleted in readstream)
ld de,DISKBUF
;ld a,0xfe
;in a,(0xfe)
;rra
ld a,(curprotocol)
;TODO что-то сделать с типом 3 - ничего
cp 2
jr nz,connect_nogopher ;http=1, gopher=2
pop hl ;filename
call strcopy
dec de
ld a,0xd
ld (de),a
inc de
ld a,0xa
ld (de),a
inc de
jr connect_makeheaderq
connect_nogopher
ld hl,tGET
call strcopy
dec de
pop hl ;filename
call strcopy
dec de
;amp.dascene.net: убрать пробел в конце url:
dec de
ld a,(de)
sub ' '
jr z,$+3
inc de
ld hl,tHTTP_host
call strcopy
dec de
ld hl,httphostname
call strcopy
dec de
ld hl,tGETend
call strcopy ;with terminator
dec de ;no terminator?
connect_makeheaderq
ex de,hl
ld de,0xffff&(-DISKBUF)
add hl,de
;send message to server:
LD a,(soc1)
LD DE,DISKBUF
;de=message
;hl=message size
;jr $
OS_WIZNETWRITE
bit 7,h
jr nz,createsoc_err
ld a,1
ld (http_firstreadflag),a
xor a ;OK
ret
;hl = poi to filename in string
;out: de = after last dot or start
findlastdot
ld d,h
ld e,l ;de = after last dot
findlastdot0
ld a,[hl]
inc hl
or a
ret z
cp '.'
jr nz,findlastdot0
jr findlastdot
tlocation
db "Location: ",0
readstream_http
ld (readstream_http_requestedsize),hl
add hl,de
push de ;начало буфера
http_firstreadflag=$+1
ld a,1
dec a
jp nz,readstream_http_nofirstread
curprotocol=$+1
ld a,0;(curprotocol)
cp 2
jp z,readstream_http_nohead ;2=gopher
;ld a,0xfe
;in a,(0xfe)
;rra
;jr nc,readstream_http_nohead ;Caps Shift - show headers
;read until cr,lf,cr,lf or EOF or endofbuf
push hl
push de
or a
sbc hl,de ;размер
jr readstream_http_headlines0
readstream_http_headretry
push de
push hl
call yieldgetkeynolang
pop hl
pop de
cp key_esc
jp z,readstream_err
display "readstream_http_head0 ", readstream_http_head0
readstream_http_headlines0
ld (readstream_http_headlineaddr),de
readstream_http_head0
push de
push hl ;размер
ld hl,1
ld a,(soc1)
OS_WIZNETREAD
bit 7,h
pop hl
pop de
jr z,readstream_http_head_ok
cp ERR_EAGAIN
jr z,readstream_http_head0 ;вдруг ответ не успел прийти
jp readstream_err
readstream_http_head_ok
dec hl ;размер
ld a,h
or l
jp z,readstream_err
ld b,d
ld c,e
inc de
ld a,(bc)
cp 0x0a
jr nz,readstream_http_head0
dec bc
ld a,(bc)
cp 0x0d
jr nz,readstream_http_head0
;dec bc
;ld a,(bc)
;cp 0x0a
;jr nz,readstream_http_head0
;dec bc
;ld a,(bc)
;cp 0x0d
;jr nz,readstream_http_head0
;если строка пустая, то readstream_http_headq
readstream_http_headlineaddr=$+1
ld a,(0) ;ok
cp 0x0d
jr z,readstream_http_headq
push de
push hl
;jr $
ld hl,(readstream_http_headlineaddr)
ld de,tlocation
;найти строку Location: <url> (если moved temporarily)
call strcp_tillde0
ld b,h
ld c,l
pop hl
pop de
jr nz,readstream_http_headlines0
;bc=url
;push bc
;копирование в текущий путь
ld hl,curfulllink - 1
.strcpy
inc hl
ld a,(bc)
ld (hl),a
inc bc
cp 0x0d
jr nz,.strcpy
xor a
ld (hl),a
call closestream_http
ld hl,curfulllink
call isprotocolpresent ;out: nz=protocol absent (hl=link), z=protocol present (a=protocol (0=file, 1=http), hl=after "//")
jr nz,readstream_http_redirect_noprotocol
ld (curprotocol),a
readstream_http_redirect_noprotocol
call openstream_http_hl
pop de
pop hl
pop de ;начало буфера
readstream_http_requestedsize=$+1
ld hl,0
;jr $
ld a,(curprotocol)
cp 3 ;https
jr z,readstream_http_redirectq ;костыль
xor a
ld (http_firstreadflag),a ;почему-то страничка, куда переадресует amp.dascene.net, отдаёт файл без http заголовка (HTTP/1.1 200 OK...)! а WoS с заголовком!
readstream_http_redirectq
jp readstream_http
readstream_http_headq
pop de
pop hl
;TODO переделать: читать как обычно, потом искать заголовок, отрезать его, сдвинуть остаток в начало буфера и прочитать ещё столько же
readstream_http_nohead
xor a
ld (http_firstreadflag),a
readstream_http_nofirstread
readstream_loop
push hl ;докуда читать
push de ;текущий ptr
or a
sbc hl,de ;размер
jr z,readstream_err
LD a,(soc1)
OS_WIZNETREAD
bit 7,h
jr z,readstream_loop_ok
cp ERR_EAGAIN
jr nz,readstream_err
ld hl,0
readstream_loop_ok
pop de ;de=куда читали, hl=сколько прочитали
add hl,de
ex de,hl ;de=текущий ptr
pop hl ;докуда читать
jr readstream_loop
readstream_err:
pop hl
pop de
pop de ;начало буфера
or a
sbc hl,de
ret
closestream_http
ld e,0
ld a,(soc1)
OS_NETSHUTDOWN
ret
curport=$+1
host_ia:
defb 0,0,80,8,8,8,8
;httpslashcurdir
db '/'
httpcurdir
;server/path (without / in the end)
ds 128
soc1
db 0 ;current socket
tGET
db "GET /",0
tHTTP_host
db " HTTP/1.0\r\n" ;1.0 DimkaM for nedopc.com
db "Connection: close\r\n"
db "Host: ",0
tGETend
db "\r\n"
db "User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)\r\n"
db "\r\n",0
;httpgetstr
;defb 'GET /cspr/index.htm HTTP/1.1',13,10
;defb 'Host: dimkam.ru',13,10
;defb 13,10
display "dns_resolver ", $
dns_resolver: ;DE-domain name
ld de,httphostname-1
ld hl,dnsbuf-1
dns_ip_loop1
inc hl
ld (hl),0
dns_ip_loop
inc de
ld a,(de)
or 0
jr nz,dns_ip_not_zero
ld hl,dnsbuf
ret
dns_ip_not_zero
cp '.'
jr z,dns_ip_loop1
sub '0'
jr c,dns_not_ip
cp 9+1
jr nc,dns_not_ip
ld c,a
ld a,(hl)
add a
ld b,a
add a
add a
add b
add c
ld (hl),a
jr dns_ip_loop
dns_not_ip
ld a,25;3
ld (dns_err_count),a
dns_err_loop
;push de
ld hl,dns_head
ld de,dnsbuf
ld bc,6
ldir
ex de,hl
ld de,dnsbuf+7
ld (hl),b;0
ld c,256-7
ldir
ld de,dnsbuf+12
ld h,d
ld l,e
ld bc, httphostname ;pop bc
name_loop:
inc hl
ld a,(bc)
ld (hl),a
inc bc
cp '.'
jr z,is_dot
or a
jr nz,name_loop
is_dot:
sbc hl,de
ex de,hl
dec e
ld (hl),e
inc e
add hl,de
ld d,h
ld e,l
or a
jr nz,name_loop
inc a
inc hl
inc hl
ld (hl),a
inc hl
inc hl
ld (hl),a
inc hl
push hl
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ld a, (dns_ia2)
cp 0
jp nz, skipgetdns
ld de, dns_ia2;DE= ptr to DNS buffer(4 bytes)
OS_GETDNS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
skipgetdns:
ld de,0x0203
OS_NETSOCKET
ld a,l
ld (soc1),a
or a
jp m,dns_exiterr
;LD DE,dns_ia
;OS_NETCONNECT
;ld a,l
;or a
;jp m,dns_exiterr
pop hl
push hl
ld de,0xffff&(-dnsbuf)
add hl,de
LD a,(soc1)
LD IX,dnsbuf
LD DE,dns_ia
OS_WIZNETWRITE
bit 7,h
jr nz,dns_exitcode
dns_err_count=$+1
ld b,25
jr recv_wait1
recv_wait:
;YIELD
push bc
call yieldgetkeynolang
pop bc
recv_wait1:
push bc
ld hl,256
LD a,(soc1)
LD DE,dnsbuf
LD IX,dnsbuf
OS_WIZNETREAD
pop bc
;ld a,h
;or l
bit 7,h
jr z,recv_wait_end
djnz recv_wait
;ld a,54 ;ERR_CONNRESET
;ld (errno),a
jr dns_exiterr
recv_wait_end:
;bit 7,h
;jr nz,dns_exitcode
;ld a,65 ;ERR_HOSTUNREACH
;ld (errno),a
ld a,(dnsbuf+3)
and 0x0f
jr nz,dns_exiterr
dns_exitcode:
LD a,(soc1)
LD E,0
OS_NETSHUTDOWN
pop hl
reqpars_l
inc hl
inc hl
inc hl
ld a,(hl)
ld de,7
add hl,de
ld b,(hl)
inc hl
ld c,(hl)
inc hl
dec a
ret z
cp 4
jr nz,exiterr1
add hl,bc
jr reqpars_l
dns_exiterr:
pop af
LD a,(soc1)
LD E,0
OS_NETSHUTDOWN
ld a,(dns_err_count)
add a,a
ld (dns_err_count),a
jp nc,dns_err_loop
exiterr1:
ld hl,0
ret
dns_head
defb 0x11,0x22,0x01,0x00,0x00,0x01
;struct sockaddr_in {unsigned char sin_family;unsigned short sin_port;
; struct in_addr sin_addr;char sin_zero[8];};
dns_ia:
defb 0
db 0,53 ;port (big endian)
dns_ia2:
db 0,0,0,0 ;ip (big endian)