emailler/ip65/url.s

312 lines
6.4 KiB
ArmAsm
Raw Normal View History

; routine for parsing a URL
2013-12-13 21:24:03 +00:00
.include "zeropage.inc"
.include "../inc/common.inc"
.include "../inc/error.inc"
2013-12-13 21:24:03 +00:00
.import output_buffer
.import ip65_error
.import parser_init
.import parser_skip_next
.import dns_set_hostname
.import dns_resolve
.import parse_integer
.import dns_ip
.export url_ip
.export url_port
.export url_selector
2013-12-13 21:24:03 +00:00
.export url_resource_type
.export url_parse
.export url_parse_buffer
2013-12-13 21:24:03 +00:00
search_string = ptr1
2013-12-13 21:24:03 +00:00
2014-04-27 16:59:58 +00:00
.bss
2013-12-13 21:24:03 +00:00
url_string: .res 2
url_ip: .res 4 ; will be set with ip address of host in url
url_port: .res 2 ; will be set with port number of url
url_selector: .res 2 ; will be set with address of selector part of URL
url_type: .res 1
url_resource_type: .res 1
url_type_unknown = 0
url_type_gopher = 1
url_type_http = 2
src_ptr: .res 1
dest_ptr: .res 1
2013-12-13 21:24:03 +00:00
.code
; parses a URL into a form that makes it easy to retrieve the specified resource
; caution - the resulting selector part of URL must fit into the output_buffer !!!
; inputs:
; AX = address of URL string
; any control character (i.e. <$20) is treated as 'end of string', e.g. a CR or LF, as well as $00
; outputs:
2013-12-13 21:24:03 +00:00
; sec if a malformed url, otherwise:
; url_ip = ip address of host in url
; url_port = port number of url
; url_selector = address of selector part of URL
2013-12-13 21:24:03 +00:00
url_parse:
2018-12-09 18:49:30 +00:00
ldy #<output_buffer
sty url_selector
ldy #>output_buffer
sty url_selector+1
; parses a URL into a form that makes it easy to retrieve the specified resource
; caution - the resulting selector part of URL must fit into the provided buffer !!!
; inputs:
; AX = address of URL string
; any control character (i.e. <$20) is treated as 'end of string', e.g. a CR or LF, as well as $00
; url_selector = points to a buffer that selector part of URL will be placed into
; outputs:
; sec if a malformed url, otherwise:
; url_ip = ip address of host in url
; url_port = port number of url
url_parse_buffer:
2013-12-13 21:24:03 +00:00
stax url_string
ldy #url_type_http
2013-12-13 21:24:03 +00:00
sty url_type
ldy #80
2013-12-13 21:24:03 +00:00
sty url_port
ldy #0
sty url_port+1
2013-12-13 21:24:03 +00:00
sty url_resource_type
jsr skip_to_hostname
bcc :+
ldax url_string
jmp @no_protocol_specifier
: ldax url_string
stax search_string
2013-12-13 21:24:03 +00:00
lda (search_string),y
cmp #'g'
2013-12-13 21:24:03 +00:00
beq @gopher
cmp #'G'
2013-12-13 21:24:03 +00:00
beq @gopher
cmp #'h'
beq @protocol_set
cmp #'H'
beq @protocol_set
@exit_with_error:
2018-02-23 15:41:33 +00:00
lda #IP65_ERROR_MALFORMED_URL
2013-12-13 21:24:03 +00:00
sta ip65_error
@exit_with_sec:
2013-12-13 21:24:03 +00:00
sec
rts
@gopher:
lda #url_type_gopher
sta url_type
lda #70
sta url_port
@protocol_set:
jsr skip_to_hostname
; now pointing at hostname
2013-12-13 21:24:03 +00:00
bcs @exit_with_error
@no_protocol_specifier:
2013-12-13 21:24:03 +00:00
jsr dns_set_hostname
bcs @exit_with_sec
jsr dns_resolve
bcc :+
2018-02-23 15:41:33 +00:00
lda #IP65_ERROR_DNS_LOOKUP_FAILED
2013-12-13 21:24:03 +00:00
sta ip65_error
jmp @exit_with_sec
: ; copy IP address
2013-12-13 21:24:03 +00:00
ldx #3
: lda dns_ip,x
2013-12-13 21:24:03 +00:00
sta url_ip,x
dex
bpl :-
jsr skip_to_hostname
; skip over next colon
2013-12-13 21:24:03 +00:00
ldax #colon
jsr parser_skip_next
bcs @no_port_in_url
; AX now point at first thing past a colon - should be a number:
jsr parse_integer
2013-12-13 21:24:03 +00:00
stax url_port
@no_port_in_url:
; skip over next slash
2013-12-13 21:24:03 +00:00
ldax #slash
jsr parser_skip_next
bcc :+
; No slash at all after hostname -> empty selector
ldax #zero
: ; AX now pointing at selector
stax ptr1
ldax url_selector
stax ptr2
2013-12-13 21:24:03 +00:00
lda #0
sta src_ptr
sta dest_ptr
lda url_type
2013-12-13 21:24:03 +00:00
cmp #url_type_gopher
bne @not_gopher
; first byte after / in a gopher url is the resource type
ldy src_ptr
lda (ptr1),y
beq @start_of_selector
2013-12-13 21:24:03 +00:00
sta url_resource_type
inc src_ptr
2013-12-13 21:24:03 +00:00
jmp @start_of_selector
@not_gopher:
2013-12-13 21:24:03 +00:00
cmp #url_type_http
beq @build_http_request
jmp @done ; if it's not gopher or http, we don't know how to build a selector
@build_http_request:
2013-12-13 21:24:03 +00:00
ldy #get_length-1
sty dest_ptr
: lda get,y
sta (ptr2),y
2013-12-13 21:24:03 +00:00
dey
bpl :-
@start_of_selector:
2013-12-13 21:24:03 +00:00
lda #'/'
inc dest_ptr
2013-12-13 21:24:03 +00:00
jmp @save_first_byte_of_selector
@copy_one_byte:
ldy src_ptr
lda (ptr1),y
2013-12-13 21:24:03 +00:00
cmp #$20
bcc @end_of_selector ; any control char (including CR,LF, and $00) should be treated as end of URL
inc src_ptr
bne @save_first_byte_of_selector
inc ptr1+1
@save_first_byte_of_selector:
ldy dest_ptr
sta (ptr2),y
2013-12-13 21:24:03 +00:00
inc dest_ptr
bne @copy_one_byte
inc ptr2+1
jmp @copy_one_byte
2013-12-13 21:24:03 +00:00
@end_of_selector:
ldx #1 ; number of CRLF at end of gopher request
2013-12-13 21:24:03 +00:00
lda url_type
2013-12-13 21:24:03 +00:00
cmp #url_type_http
bne @final_crlf
; now the HTTP version number & Host: field
2013-12-13 21:24:03 +00:00
ldx #0
: lda http_preamble,x
beq :++
2013-12-13 21:24:03 +00:00
ldy dest_ptr
sta (ptr2),y
inc dest_ptr
bne :+
inc ptr2+1
: inx
bne :--
: ; now copy the host field
lda ptr2+1
pha
2013-12-13 21:24:03 +00:00
jsr skip_to_hostname
; AX now pointing at hostname
stax ptr1
lda url_selector
sta ptr2
pla
sta ptr2+1
2013-12-13 21:24:03 +00:00
lda #0
sta src_ptr
2013-12-13 21:24:03 +00:00
@copy_one_byte_of_hostname:
ldy src_ptr
lda (ptr1),y
2013-12-13 21:24:03 +00:00
beq @end_of_hostname
cmp #':'
beq @end_of_hostname
cmp #'/'
beq @end_of_hostname
inc src_ptr
ldy dest_ptr
sta (ptr2),y
inc dest_ptr
2013-12-13 21:24:03 +00:00
bne @copy_one_byte_of_hostname
inc ptr2+1
jmp @copy_one_byte_of_hostname
2013-12-13 21:24:03 +00:00
@end_of_hostname:
ldx #2 ; number of CRLF at end of HTTP request
2013-12-13 21:24:03 +00:00
@final_crlf:
ldy dest_ptr
lda #$0d
sta (ptr2),y
2013-12-13 21:24:03 +00:00
iny
bne :+
inc ptr2+1
: lda #$0a
sta (ptr2),y
2013-12-13 21:24:03 +00:00
iny
bne :+
inc ptr2+1
: sty dest_ptr
2013-12-13 21:24:03 +00:00
dex
bne @final_crlf
@done:
2013-12-13 21:24:03 +00:00
lda #$00
sta (ptr2),y
2013-12-13 21:24:03 +00:00
clc
rts
2013-12-13 21:24:03 +00:00
skip_to_hostname:
ldax url_string
jsr parser_init
ldax #colon_slash_slash
jmp parser_skip_next
.rodata
get:
.byte "GET "
get_length = 4
http_preamble:
.byte " HTTP/1.0",$0d,$0a
.byte "User-Agent: IP65/0.65",$0d,$0a
.byte "Connection: close",$0d,$0a
.byte "Host: ",0
colon_slash_slash:
.byte ":/"
slash:
.byte "/"
zero:
.byte 0
colon:
.byte ":",0
; -- LICENSE FOR url.s --
2013-12-13 21:24:03 +00:00
; The contents of this file are subject to the Mozilla Public License
; Version 1.1 (the "License"); you may not use this file except in
; compliance with the License. You may obtain a copy of the License at
; http://www.mozilla.org/MPL/
;
2013-12-13 21:24:03 +00:00
; Software distributed under the License is distributed on an "AS IS"
; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
; License for the specific language governing rights and limitations
; under the License.
;
2013-12-13 21:24:03 +00:00
; The Original Code is ip65.
;
2013-12-13 21:24:03 +00:00
; The Initial Developer of the Original Code is Jonno Downes,
; jonno@jamtronix.com.
; Portions created by the Initial Developer are Copyright (C) 2009
; Jonno Downes. All Rights Reserved.
2013-12-13 21:24:03 +00:00
; -- LICENSE END --