2013-12-27 13:57:56 +00:00
; routines for parsing a HTTP request
; to use - first call http_parse_request, then call http_get_value to get method name, path, and variable values
; NB - this routine uses the same buffer space and zero page locations as many other ip65 routines. so do not call
; other ip65 routines between the http_parse_request & http_get_value else odd things will happen.
2013-12-13 21:24:03 +00:00
2014-07-07 18:56:21 +00:00
.include " zeropage. i n c "
2018-02-23 15:36:05 +00:00
.include " . . / inc/ c o m m o n . i n c "
2013-12-13 21:24:03 +00:00
.export http_parse_request
.export http_get_value
.import output_buffer
.import parse_hex_digits
2013-12-27 13:57:56 +00:00
2014-07-07 18:56:21 +00:00
string_ p t r = p t r1
table_ p t r = p t r2
2013-12-13 21:24:03 +00:00
.bss
2013-12-27 13:57:56 +00:00
2014-04-27 16:15:10 +00:00
var_buf : .res $ 300 ; work area for storing variables extracted from query string
2013-12-27 13:57:56 +00:00
var_name : .res 1
2013-12-13 21:24:03 +00:00
hex_digit : .res 1
2013-12-27 13:57:56 +00:00
.code
2013-12-13 21:24:03 +00:00
2013-12-27 13:57:56 +00:00
; split a HTTP request into method (e.g. GET or POST), the path, and any querystring variables
; NB only the first letter in a variable name is significant. i.e. if a querystring contains variables 'a','alpha' & 'alabama', only the first one in will be retreivable.
; the method is stored in var $01
; the path is stored in var $02
; for example, parsing "GET /goober?a=foo&alpha=beta" would result in:
; value of A when calling http_get_value value returned by http_get_value
; #$01 "GET"
; #$02 "/goober"
; #'a' "foo"
; #'A' (error)
; inputs:
; AX = pointer to HTTP request
; outputs:
2013-12-13 21:24:03 +00:00
; none - but values can be retrieved through subsequent calls to http_get_value
http_parse_request :
stax s t r i n g _ p t r
2013-12-27 13:57:56 +00:00
2014-04-28 16:34:56 +00:00
ldax #v a r _ b u f
2013-12-27 13:57:56 +00:00
stax t a b l e _ p t r
lda #1 ; start of method
ldy #0
2013-12-13 21:24:03 +00:00
jsr p u t _ b y t e
lda ( s t r i n g _ p t r ) ,y
cmp #' / '
beq @gopher
jsr @check_end_of_string
bcs @gopher
lda ( s t r i n g _ p t r ) ,y
@extract_method:
cmp #' '
beq @end_of_method
jsr @check_end_of_string
bcc : +
jmp @done
2013-12-27 13:57:56 +00:00
: jsr p u t _ b y t e
2013-12-13 21:24:03 +00:00
jsr g e t _ n e x t _ b y t e _ i n _ s o u r c e
jmp @extract_method
@gopher:
jsr @output_end_of_method
2013-12-27 13:57:56 +00:00
lda #' / '
2013-12-13 21:24:03 +00:00
jmp @got_path_char
2013-12-27 13:57:56 +00:00
@output_end_of_method:
lda #0 ; end of method
2013-12-13 21:24:03 +00:00
jsr p u t _ b y t e
2013-12-27 13:57:56 +00:00
lda #2 ; start of path
2013-12-13 21:24:03 +00:00
jmp p u t _ b y t e
@end_of_method:
jsr @output_end_of_method
2013-12-27 13:57:56 +00:00
2013-12-13 21:24:03 +00:00
@extract_path:
jsr g e t _ n e x t _ b y t e _ i n _ s o u r c e
jsr @check_end_of_string
bcs @done
cmp #' ? '
beq @end_of_path
cmp #' & '
beq @end_of_path
2013-12-27 13:57:56 +00:00
@got_path_char:
2013-12-13 21:24:03 +00:00
jsr p u t _ b y t e
jmp @extract_path
2013-12-27 13:57:56 +00:00
@end_of_path:
lda #0 ; end of path
2013-12-13 21:24:03 +00:00
jsr p u t _ b y t e
2013-12-27 13:57:56 +00:00
@next_var:
2013-12-13 21:24:03 +00:00
jsr g e t _ n e x t _ b y t e _ i n _ s o u r c e
jsr @check_end_of_string
bcs @done
jsr p u t _ b y t e
2013-12-27 13:57:56 +00:00
2013-12-13 21:24:03 +00:00
@skip_to_equals:
jsr g e t _ n e x t _ b y t e _ i n _ s o u r c e
jsr @check_end_of_string
bcs @done
cmp #' ? '
beq @next_var
cmp #' & '
2013-12-27 13:57:56 +00:00
beq @next_var
2013-12-13 21:24:03 +00:00
cmp #' = '
beq @got_var
jmp @skip_to_equals
2013-12-27 13:57:56 +00:00
@got_var:
2013-12-13 21:24:03 +00:00
jsr g e t _ n e x t _ b y t e _ i n _ s o u r c e
jsr @check_end_of_string
bcs @done
cmp #' ? '
beq @end_of_var
cmp #' & '
beq @end_of_var
2013-12-27 13:57:56 +00:00
2013-12-13 21:24:03 +00:00
cmp #' % '
beq @get_percent_encoded_byte
cmp #' + '
bne : +
lda #' '
:
@got_byte:
2013-12-27 13:57:56 +00:00
jsr p u t _ b y t e
2013-12-13 21:24:03 +00:00
jmp @got_var
2013-12-27 13:57:56 +00:00
@end_of_var:
2013-12-13 21:24:03 +00:00
lda #0
jsr p u t _ b y t e
jmp @next_var
2013-12-27 13:57:56 +00:00
2013-12-13 21:24:03 +00:00
@done:
lda #0
jsr p u t _ b y t e
jsr p u t _ b y t e
rts
@check_end_of_string:
cmp #0
beq @end_of_string
cmp #' '
beq @end_of_string
cmp #$ 0 a
beq @end_of_string
cmp #$ 0 d
beq @end_of_string
clc
rts
@end_of_string:
sec
rts
2013-12-27 13:57:56 +00:00
2013-12-13 21:24:03 +00:00
@get_percent_encoded_byte:
jsr g e t _ n e x t _ b y t e _ i n _ s o u r c e
tax
jsr g e t _ n e x t _ b y t e _ i n _ s o u r c e
jsr p a r s e _ h e x _ d i g i t s
jmp @got_byte
2013-12-27 13:57:56 +00:00
2013-12-13 21:24:03 +00:00
put_byte :
sta ( t a b l e _ p t r ) ,y
inc t a b l e _ p t r
bne : +
inc t a b l e _ p t r + 1
2013-12-27 13:57:56 +00:00
: rts
; retrieve the value of a variable defined in the previously parsed HTTP request.
; inputs:
; A = variable to retrieve.
; to get the method (GET/POST/HEAD), pass A=$01.
; to get the path (everything between the method and the first '?'), pass A=$02.
; outputs:
2013-12-13 21:24:03 +00:00
; if variable exists in HTTP request, carry flag will be clear and AX points to value (null terminated string)
; if variable did not exist, carry flag will be set.
http_get_value :
sta v a r _ n a m e
2014-04-28 16:34:56 +00:00
ldax #v a r _ b u f
2013-12-13 21:24:03 +00:00
stax s t r i n g _ p t r
ldy #0
lda ( s t r i n g _ p t r ) ,y
@check_next_var:
beq @end_of_vars
cmp v a r _ n a m e
beq @got_var
2013-12-27 13:57:56 +00:00
; not the var we want, so skip over till next byte
2013-12-13 21:24:03 +00:00
@skip_till_null_byte:
2013-12-27 13:57:56 +00:00
jsr g e t _ n e x t _ b y t e _ i n _ s o u r c e
2013-12-13 21:24:03 +00:00
bne @skip_till_null_byte
2013-12-27 13:57:56 +00:00
jsr g e t _ n e x t _ b y t e _ i n _ s o u r c e
2013-12-13 21:24:03 +00:00
bne @check_next_var
2013-12-27 13:57:56 +00:00
2013-12-13 21:24:03 +00:00
@end_of_vars:
sec
rts
@got_var:
jsr g e t _ n e x t _ b y t e _ i n _ s o u r c e
ldax s t r i n g _ p t r
clc
rts
2013-12-27 13:57:56 +00:00
2013-12-13 21:24:03 +00:00
get_next_byte_in_source :
inc s t r i n g _ p t r
bne : +
inc s t r i n g _ p t r + 1
2013-12-27 13:57:56 +00:00
: lda ( s t r i n g _ p t r ) ,y
2013-12-13 21:24:03 +00:00
rts
2013-12-27 13:57:56 +00:00
; -- LICENSE FOR http.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-27 13:57:56 +00:00
;
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-27 13:57:56 +00:00
;
2013-12-13 21:24:03 +00:00
; The Original Code is ip65.
2013-12-27 13:57:56 +00:00
;
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
2013-12-27 13:57:56 +00:00
; Jonno Downes. All Rights Reserved.
2013-12-13 21:24:03 +00:00
; -- LICENSE END --