mirror of
https://github.com/bobbimanners/emailler.git
synced 2024-06-25 23:29:34 +00:00
Factored out W5100 HTTP client handling.
In order to reduce code duplication for a planned W5100 HTTP client program beside wget65 the W5100 HTTP client code is now available for reuse.
This commit is contained in:
parent
bbd2906f6f
commit
f9e28e79b9
|
@ -46,7 +46,7 @@ TCP =\
|
|||
|
||||
bin: wget65.bin
|
||||
|
||||
wget65.bin: w5100.c linenoise.c
|
||||
wget65.bin: w5100.c w5100_http.c linenoise.c
|
||||
wget65.bin: IP65LIB = ../ip65/ip65.lib
|
||||
wget65.bin: A2_DRIVERLIB = ../drivers/ip65_apple2_uther2.lib
|
||||
|
||||
|
|
185
apps/w5100_http.c
Normal file
185
apps/w5100_http.c
Normal file
|
@ -0,0 +1,185 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2020, Oliver Schmidt
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL OLIVER SCHMIDT BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../inc/ip65.h"
|
||||
#include "w5100.h"
|
||||
#include "w5100_http.h"
|
||||
|
||||
// Both pragmas are obligatory to have cc65 generate code
|
||||
// suitable to access the W5100 auto-increment registers.
|
||||
#pragma optimize (on)
|
||||
#pragma static-locals (on)
|
||||
|
||||
bool w5100_http_open(uint32_t addr, uint16_t port, const char* selector,
|
||||
char* buffer, size_t length)
|
||||
{
|
||||
printf("Connecting to %s:%d ", dotted_quad(addr), port);
|
||||
|
||||
if (!w5100_connect(addr, port))
|
||||
{
|
||||
printf("- Connect failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("- Ok\n\nSending request ");
|
||||
{
|
||||
uint16_t snd;
|
||||
uint16_t pos = 0;
|
||||
uint16_t len = strlen(selector);
|
||||
|
||||
while (len)
|
||||
{
|
||||
if (input_check_for_abort_key())
|
||||
{
|
||||
printf("- User abort\n");
|
||||
w5100_disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
snd = w5100_send_request();
|
||||
if (!snd)
|
||||
{
|
||||
if (!w5100_connected())
|
||||
{
|
||||
printf("- Connection lost\n");
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len < snd)
|
||||
{
|
||||
snd = len;
|
||||
}
|
||||
|
||||
{
|
||||
// One less to allow for faster pre-increment below
|
||||
const char *dataptr = selector + pos - 1;
|
||||
uint16_t i;
|
||||
for (i = 0; i < snd; ++i)
|
||||
{
|
||||
// The variable is necessary to have cc65 generate code
|
||||
// suitable to access the W5100 auto-increment register.
|
||||
char data = *++dataptr;
|
||||
*w5100_data = data;
|
||||
}
|
||||
}
|
||||
|
||||
w5100_send_commit(snd);
|
||||
len -= snd;
|
||||
pos += snd;
|
||||
}
|
||||
}
|
||||
|
||||
printf("- Ok\n\nReceiving response ");
|
||||
{
|
||||
uint16_t rcv;
|
||||
bool body = false;
|
||||
uint16_t len = 0;
|
||||
|
||||
while (!body)
|
||||
{
|
||||
if (input_check_for_abort_key())
|
||||
{
|
||||
printf("- User abort\n");
|
||||
w5100_disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
rcv = w5100_receive_request();
|
||||
if (!rcv)
|
||||
{
|
||||
if (!w5100_connected())
|
||||
{
|
||||
printf("- Connection lost\n");
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rcv > length - len)
|
||||
{
|
||||
rcv = length - len;
|
||||
}
|
||||
|
||||
{
|
||||
// One less to allow for faster pre-increment below
|
||||
char *dataptr = buffer + len - 1;
|
||||
uint16_t i;
|
||||
for (i = 0; i < rcv; ++i)
|
||||
{
|
||||
// The variable is necessary to have cc65 generate code
|
||||
// suitable to access the W5100 auto-increment register.
|
||||
char data = *w5100_data;
|
||||
*++dataptr = data;
|
||||
|
||||
if (!memcmp(dataptr - 3, "\r\n\r\n", 4))
|
||||
{
|
||||
rcv = i + 1;
|
||||
body = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
w5100_receive_commit(rcv);
|
||||
len += rcv;
|
||||
|
||||
// No body found in full buffer
|
||||
if (len == sizeof(buffer))
|
||||
{
|
||||
printf("- Invalid response\n");
|
||||
w5100_disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace "HTTP/1.1" with "HTTP/1.0"
|
||||
buffer[7] = '0';
|
||||
|
||||
if (memcmp(buffer, "HTTP/1.0 200", 12))
|
||||
{
|
||||
if (!memcmp(buffer, "HTTP/1.0", 8))
|
||||
{
|
||||
char *eol = strchr(buffer,'\r');
|
||||
*eol = '\0';
|
||||
printf("- Status%s\n", buffer + 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("- Unknown response\n");
|
||||
}
|
||||
w5100_disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
48
apps/w5100_http.h
Normal file
48
apps/w5100_http.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2020, Oliver Schmidt
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL OLIVER SCHMIDT BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _W5100_HTTP_H_
|
||||
#define _W5100_HTTP_H_
|
||||
|
||||
#ifndef __APPLE2ENH__
|
||||
#error W5100 auto-increment register access requires 65C02.
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Connect to server with IP address <server_addr> on TCP port <server_port>,
|
||||
// then HTTP GET <selector> and consume HTTP response header. Provide feedback
|
||||
// on progress to the user via STDOUT. After returning from w5100_http_open()
|
||||
// the connection is ready to consume the HTTP body.
|
||||
// Return true if the connection is established, return false otherwise.
|
||||
bool w5100_http_open(uint32_t addr, uint16_t port, const char* selector,
|
||||
char* buffer, size_t length);
|
||||
|
||||
#endif
|
150
apps/wget65.c
150
apps/wget65.c
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "../inc/ip65.h"
|
||||
#include "w5100.h"
|
||||
#include "w5100_http.h"
|
||||
#include "linenoise.h"
|
||||
|
||||
// Both pragmas are obligatory to have cc65 generate code
|
||||
|
@ -24,13 +25,10 @@
|
|||
char buffer[0x1000];
|
||||
char name[16];
|
||||
|
||||
void ip65_error_exit(bool quit)
|
||||
void ip65_error_exit(void)
|
||||
{
|
||||
printf("- %s\n", ip65_strerror(ip65_error));
|
||||
if (quit)
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void file_error_exit(void)
|
||||
|
@ -241,15 +239,6 @@ void exit_on_key(void)
|
|||
}
|
||||
}
|
||||
|
||||
void exit_on_disconnect(void)
|
||||
{
|
||||
if (!w5100_connected())
|
||||
{
|
||||
printf("- Connection lost\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void write_file(const char *name)
|
||||
{
|
||||
uint16_t i;
|
||||
|
@ -490,10 +479,10 @@ int main(int, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
printf("- %d\n\nInitializing ", eth_init);
|
||||
printf("- %d\n\nInitializing %s ", eth_init, eth_name);
|
||||
if (ip65_init(eth_init))
|
||||
{
|
||||
ip65_error_exit(true);
|
||||
ip65_error_exit();
|
||||
}
|
||||
|
||||
// Abort on Ctrl-C to be consistent with Linenoise
|
||||
|
@ -502,7 +491,7 @@ int main(int, char *argv[])
|
|||
printf("- Ok\n\nObtaining IP address ");
|
||||
if (dhcp_init())
|
||||
{
|
||||
ip65_error_exit(true);
|
||||
ip65_error_exit();
|
||||
}
|
||||
printf("- Ok\n\n");
|
||||
|
||||
|
@ -520,9 +509,7 @@ int main(int, char *argv[])
|
|||
break;
|
||||
}
|
||||
|
||||
// Do not actually exit
|
||||
ip65_error_exit(false);
|
||||
printf("\n");
|
||||
printf("- %s\n\n", ip65_strerror(ip65_error));
|
||||
}
|
||||
save_argument("wget.urls");
|
||||
printf("- Ok\n\n");
|
||||
|
@ -632,7 +619,8 @@ int main(int, char *argv[])
|
|||
char oldcursor;
|
||||
char c;
|
||||
|
||||
printf("- Ok\n\nClobber %s? ", buffer);
|
||||
printf("- Ok\n\n");
|
||||
cprintf("Clobber %s? ", buffer);
|
||||
|
||||
oldcursor = cursor(true);
|
||||
c = cgetc();
|
||||
|
@ -668,124 +656,10 @@ int main(int, char *argv[])
|
|||
}
|
||||
save_argument("wget.files");
|
||||
|
||||
printf("\n\nConnecting to %s:%d ", dotted_quad(url_ip), url_port);
|
||||
|
||||
if (!w5100_connect(url_ip, url_port))
|
||||
printf("\n\n");
|
||||
if (!w5100_http_open(url_ip, url_port, url_selector, buffer, sizeof(buffer)))
|
||||
{
|
||||
printf("- Connect failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("- Ok\n\nSending request ");
|
||||
{
|
||||
uint16_t snd;
|
||||
uint16_t pos = 0;
|
||||
uint16_t len = strlen(url_selector);
|
||||
|
||||
while (len)
|
||||
{
|
||||
exit_on_key();
|
||||
|
||||
snd = w5100_send_request();
|
||||
if (!snd)
|
||||
{
|
||||
exit_on_disconnect();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len < snd)
|
||||
{
|
||||
snd = len;
|
||||
}
|
||||
|
||||
{
|
||||
// One less to allow for faster pre-increment below
|
||||
char *dataptr = url_selector + pos - 1;
|
||||
for (i = 0; i < snd; ++i)
|
||||
{
|
||||
// The variable is necessary to have cc65 generate code
|
||||
// suitable to access the W5100 auto-increment register.
|
||||
char data = *++dataptr;
|
||||
*w5100_data = data;
|
||||
}
|
||||
}
|
||||
|
||||
w5100_send_commit(snd);
|
||||
len -= snd;
|
||||
pos += snd;
|
||||
}
|
||||
}
|
||||
|
||||
printf("- Ok\n\nReceiving response ");
|
||||
{
|
||||
uint16_t rcv;
|
||||
bool body = false;
|
||||
uint16_t len = 0;
|
||||
|
||||
while (!body)
|
||||
{
|
||||
exit_on_key();
|
||||
|
||||
rcv = w5100_receive_request();
|
||||
if (!rcv)
|
||||
{
|
||||
exit_on_disconnect();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rcv > sizeof(buffer) - len)
|
||||
{
|
||||
rcv = sizeof(buffer) - len;
|
||||
}
|
||||
|
||||
{
|
||||
// One less to allow for faster pre-increment below
|
||||
char *dataptr = buffer + len - 1;
|
||||
for (i = 0; i < rcv; ++i)
|
||||
{
|
||||
// The variable is necessary to have cc65 generate code
|
||||
// suitable to access the W5100 auto-increment register.
|
||||
char data = *w5100_data;
|
||||
*++dataptr = data;
|
||||
|
||||
if (!memcmp(dataptr - 3, "\r\n\r\n", 4))
|
||||
{
|
||||
rcv = i + 1;
|
||||
body = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
w5100_receive_commit(rcv);
|
||||
len += rcv;
|
||||
|
||||
// No body found in full buffer
|
||||
if (len == sizeof(buffer))
|
||||
{
|
||||
printf("- Invalid response\n");
|
||||
w5100_disconnect();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace "HTTP/1.1" with "HTTP/1.0"
|
||||
buffer[7] = '0';
|
||||
|
||||
if (!match("HTTP/1.0 200", buffer))
|
||||
{
|
||||
if (match("HTTP/1.0", buffer))
|
||||
{
|
||||
char *eol = strchr(buffer,'\r');
|
||||
*eol = '\0';
|
||||
printf("- Status%s\n", buffer + 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("- Unknown response\n");
|
||||
}
|
||||
w5100_disconnect();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (device)
|
||||
|
|
Loading…
Reference in New Issue
Block a user