From 6a296b2058c950ba6add3ee821c7919eae7914ce Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Tue, 13 Nov 2018 13:14:49 +0100 Subject: [PATCH] Improved URL selector handling. parse_url stores the URL selector in the output_buffer - which is currently 520 bytes. A new entry point called parse_url_buffer was added which instead stores the URL selector in a buffer provided by the user. url_download now calls the new parse_url_buffer instead of parse_url. The buffer for the URL selector is simply the download_buffer. So the download_buffer is used twice: First to hold the URL selector to be sent as request to the server and then to hold the response received from the server. However, the URL selector still can't exceed the MSS (aka 1460 bytes). Note: The User-Agent string was shortened by two bytes as that allows a "default" URL (incl. 'http://' but without port number) of exactly 1400 bytes to end up as 1460 bytes URL selector. --- apps/ifttt.c | 6 +++--- apps/tweet65.c | 3 +++ inc/ip65.h | 7 ++++--- ip65/download.s | 24 ++++++++++++++---------- ip65/tcp.s | 2 +- ip65/url.s | 26 +++++++++++++++++++------- 6 files changed, 44 insertions(+), 24 deletions(-) diff --git a/apps/ifttt.c b/apps/ifttt.c index fa7d132..86070ca 100644 --- a/apps/ifttt.c +++ b/apps/ifttt.c @@ -6,8 +6,8 @@ #include "../inc/ip65.h" #include "ifttt.h" -static char url[1024]; -static char download[1024]; +static char url[2048]; +static char download[2048]; static bool isclean(char c) { @@ -85,7 +85,7 @@ int ifttt_trigger(const char* key, const char* event, ++ptr; } - if (strlen(url) > 450) + if (strlen(url) > 1400) { ip65_error = IP65_ERROR_MALFORMED_URL; return -1; diff --git a/apps/tweet65.c b/apps/tweet65.c index 43efbc8..b8f91b9 100644 --- a/apps/tweet65.c +++ b/apps/tweet65.c @@ -28,6 +28,9 @@ void error_exit(void) case IP65_ERROR_TIMEOUT_ON_RECEIVE: printf("- Timeout\n"); break; + case IP65_ERROR_MALFORMED_URL: + printf("- Malformed URL\n"); + break; case IP65_ERROR_DNS_LOOKUP_FAILED: printf("- Lookup failed\n"); break; diff --git a/inc/ip65.h b/inc/ip65.h index 83b5a8b..7e8150b 100644 --- a/inc/ip65.h +++ b/inc/ip65.h @@ -213,7 +213,7 @@ bool tcp_close(void); // Send data on the current TCP connection // // Inputs: buf: Pointer to buffer containing data to be sent -// len: Length of data to send (exclusive of any headers) +// len: Length of data to send (up to 1460 bytes) // Output: true if an error occured, false otherwise // bool __fastcall__ tcp_send(const uint8_t* buf, uint16_t len); @@ -299,8 +299,9 @@ extern char* url_selector; // Zero terminated string containing selector pa // Download a resource specified by an HTTP URL // -// The URL mustn't be longer than 450 chars. -// On success the resource is zero terminated. +// The URL mustn't be longer than 1400 chars. The buffer is temporarily used to hold the +// generated HTTP request so it should have a length of at least 1460 bytes. On success +// the resource is zero terminated. // // Inputs: url: Zero (or ctrl char) terminated string containing the URL // buf: Pointer to a buffer that the resource will be downloaded into diff --git a/ip65/download.s b/ip65/download.s index e31fac5..459a03a 100644 --- a/ip65/download.s +++ b/ip65/download.s @@ -21,7 +21,7 @@ TIMEOUT_SECONDS = 15 .import url_ip .import url_port .import url_selector -.import url_parse +.import url_parse_buffer .export url_download .export url_download_buffer @@ -47,17 +47,21 @@ TIMEOUT_SECONDS = 15 .code ; download a resource specified by an URL -; caution - the selector built from the URL must fit into the output_buffer !!! +; caution - the selector built from the URL must fit into the url_download_buffer !!! ; inputs: ; AX = address of URL string -; url_download_buffer - points to a buffer that url will be downloaded into -; url_download_buffer_length - length of buffer +; url_download_buffer = points to a buffer that url will be downloaded into +; url_download_buffer_length = length of buffer ; outputs: ; sec if an error occured, else buffer pointed at by url_download_buffer is filled with contents ; of specified resource (with an extra 2 null bytes at the end), ; AX = length of resource downloaded. url_download: - jsr url_parse + ldy url_download_buffer + sty url_selector + ldy url_download_buffer+1 + sty url_selector+1 + jsr url_parse_buffer bcc resource_download rts @@ -65,9 +69,9 @@ url_download: ; inputs: ; url_ip = ip address of host to connect to ; url_port = port number of to connect to -; url_selector= address of selector to send to host after connecting -; url_download_buffer - points to a buffer that url will be downloaded into -; url_download_buffer_length - length of buffer +; url_selector = address of selector to send to host after connecting +; url_download_buffer = points to a buffer that url will be downloaded into +; url_download_buffer_length = length of buffer ; outputs: ; sec if an error occured, else buffer pointed at by url_download_buffer is filled with contents ; of specified resource (with an extra 2 null bytes at the end). @@ -76,7 +80,6 @@ resource_download: stax resource_buffer ldax url_download_buffer_length stax resource_buffer_length - jsr put_zero_at_end_of_dl_buffer ldx #3 ; save IP address just retrieved : lda url_ip,x @@ -94,8 +97,9 @@ resource_download: ldx #0 stx download_flag ldax url_selector - jsr tcp_send_string + + jsr put_zero_at_end_of_dl_buffer jsr timer_read txa adc #TIMEOUT_SECONDS*4 ; what value should trigger the timeout? diff --git a/ip65/tcp.s b/ip65/tcp.s index 99ace49..7e306c3 100644 --- a/ip65/tcp.s +++ b/ip65/tcp.s @@ -398,7 +398,7 @@ tcp_send_string: ; send tcp data ; inputs: ; tcp connection should already be opened -; tcp_send_data_len: length of data to send (exclusive of any headers) +; tcp_send_data_len: length of data to send (up to 1460 bytes) ; AX: pointer to buffer containing data to be sent ; outputs: ; carry flag is set if an error occured, clear otherwise diff --git a/ip65/url.s b/ip65/url.s index 3fe7f83..a46d06d 100644 --- a/ip65/url.s +++ b/ip65/url.s @@ -18,9 +18,9 @@ .export url_selector .export url_resource_type .export url_parse +.export url_parse_buffer search_string = ptr1 -selector_buffer = output_buffer .bss @@ -50,8 +50,22 @@ selector_buffer = output_buffer ; 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 +; url_selector = address of selector part of URL url_parse: + ldax #output_buffer + stax url_selector + +; 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: stax url_string ldy #url_type_http sty url_type @@ -125,7 +139,7 @@ lda #url_type_gopher ldax #zero : ; AX now pointing at selector stax ptr1 - ldax #selector_buffer + ldax url_selector stax ptr2 lda #0 sta src_ptr @@ -196,7 +210,7 @@ lda #url_type_gopher jsr skip_to_hostname ; AX now pointing at hostname stax ptr1 - ldax #