Merge pull request #1112 from oliverschmidt/master
Various improvements of the HTTP client and web browser.
This commit is contained in:
commit
c9edb9006b
|
@ -9,7 +9,6 @@ html_a "a\0"
|
||||||
html_body "body\0"
|
html_body "body\0"
|
||||||
html_br "br\0"
|
html_br "br\0"
|
||||||
html_form "form\0"
|
html_form "form\0"
|
||||||
html_frame "frame\0"
|
|
||||||
html_h1 "h1\0"
|
html_h1 "h1\0"
|
||||||
html_h2 "h2\0"
|
html_h2 "h2\0"
|
||||||
html_h3 "h3\0"
|
html_h3 "h3\0"
|
||||||
|
|
|
@ -31,9 +31,6 @@ const char html_br[4] =
|
||||||
const char html_form[6] =
|
const char html_form[6] =
|
||||||
/* "form\0" */
|
/* "form\0" */
|
||||||
{0x66, 0x6f, 0x72, 0x6d, 00, };
|
{0x66, 0x6f, 0x72, 0x6d, 00, };
|
||||||
const char html_frame[7] =
|
|
||||||
/* "frame\0" */
|
|
||||||
{0x66, 0x72, 0x61, 0x6d, 0x65, 00, };
|
|
||||||
const char html_h1[4] =
|
const char html_h1[4] =
|
||||||
/* "h1\0" */
|
/* "h1\0" */
|
||||||
{0x68, 0x31, 00, };
|
{0x68, 0x31, 00, };
|
||||||
|
|
|
@ -9,7 +9,6 @@ extern const char html_a[3];
|
||||||
extern const char html_body[6];
|
extern const char html_body[6];
|
||||||
extern const char html_br[4];
|
extern const char html_br[4];
|
||||||
extern const char html_form[6];
|
extern const char html_form[6];
|
||||||
extern const char html_frame[7];
|
|
||||||
extern const char html_h1[4];
|
extern const char html_h1[4];
|
||||||
extern const char html_h2[4];
|
extern const char html_h2[4];
|
||||||
extern const char html_h3[4];
|
extern const char html_h3[4];
|
||||||
|
|
|
@ -119,9 +119,6 @@ G * (<br>, <p>, <h>), the <li> tag (but does not even try to
|
||||||
#define ISO_eq 0x3d
|
#define ISO_eq 0x3d
|
||||||
#define ISO_gt 0x3e
|
#define ISO_gt 0x3e
|
||||||
|
|
||||||
#define ISO_rbrack 0x5b
|
|
||||||
#define ISO_lbrack 0x5d
|
|
||||||
|
|
||||||
#define MINORSTATE_NONE 0
|
#define MINORSTATE_NONE 0
|
||||||
#define MINORSTATE_TEXT 1 /* Parse normal text */
|
#define MINORSTATE_TEXT 1 /* Parse normal text */
|
||||||
#define MINORSTATE_EXTCHAR 2 /* Check for semi-colon */
|
#define MINORSTATE_EXTCHAR 2 /* Check for semi-colon */
|
||||||
|
@ -140,7 +137,7 @@ G * (<br>, <p>, <h>), the <li> tag (but does not even try to
|
||||||
#define MAJORSTATE_LINK 2
|
#define MAJORSTATE_LINK 2
|
||||||
#define MAJORSTATE_FORM 3
|
#define MAJORSTATE_FORM 3
|
||||||
#define MAJORSTATE_DISCARD 4
|
#define MAJORSTATE_DISCARD 4
|
||||||
|
#define MAJORSTATE_SCRIPT 5
|
||||||
|
|
||||||
struct htmlparser_state {
|
struct htmlparser_state {
|
||||||
|
|
||||||
|
@ -151,7 +148,7 @@ struct htmlparser_state {
|
||||||
unsigned char tagattrptr;
|
unsigned char tagattrptr;
|
||||||
char tagattrparam[WWW_CONF_MAX_URLLEN + 1];
|
char tagattrparam[WWW_CONF_MAX_URLLEN + 1];
|
||||||
unsigned char tagattrparamptr;
|
unsigned char tagattrparamptr;
|
||||||
unsigned char lastchar, quotechar;
|
unsigned char quotechar;
|
||||||
unsigned char majorstate, lastmajorstate;
|
unsigned char majorstate, lastmajorstate;
|
||||||
char linkurl[WWW_CONF_MAX_URLLEN + 1];
|
char linkurl[WWW_CONF_MAX_URLLEN + 1];
|
||||||
|
|
||||||
|
@ -196,33 +193,31 @@ static const char *tags[] = {
|
||||||
html_br,
|
html_br,
|
||||||
#define TAG_FORM 10
|
#define TAG_FORM 10
|
||||||
html_form,
|
html_form,
|
||||||
#define TAG_FRAME 11
|
#define TAG_H1 11
|
||||||
html_frame,
|
|
||||||
#define TAG_H1 12
|
|
||||||
html_h1,
|
html_h1,
|
||||||
#define TAG_H2 13
|
#define TAG_H2 12
|
||||||
html_h2,
|
html_h2,
|
||||||
#define TAG_H3 14
|
#define TAG_H3 13
|
||||||
html_h3,
|
html_h3,
|
||||||
#define TAG_H4 15
|
#define TAG_H4 14
|
||||||
html_h4,
|
html_h4,
|
||||||
#define TAG_IMG 16
|
#define TAG_IMG 15
|
||||||
html_img,
|
html_img,
|
||||||
#define TAG_INPUT 17
|
#define TAG_INPUT 16
|
||||||
html_input,
|
html_input,
|
||||||
#define TAG_LI 18
|
#define TAG_LI 17
|
||||||
html_li,
|
html_li,
|
||||||
#define TAG_P 19
|
#define TAG_P 18
|
||||||
html_p,
|
html_p,
|
||||||
#define TAG_SCRIPT 20
|
#define TAG_SCRIPT 19
|
||||||
html_script,
|
html_script,
|
||||||
#define TAG_SELECT 21
|
#define TAG_SELECT 20
|
||||||
html_select,
|
html_select,
|
||||||
#define TAG_STYLE 22
|
#define TAG_STYLE 21
|
||||||
html_style,
|
html_style,
|
||||||
#define TAG_TR 23
|
#define TAG_TR 22
|
||||||
html_tr,
|
html_tr,
|
||||||
#define TAG_LAST 24
|
#define TAG_LAST 23
|
||||||
last,
|
last,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -254,7 +249,7 @@ htmlparser_init(void)
|
||||||
{
|
{
|
||||||
s.majorstate = s.lastmajorstate = MAJORSTATE_DISCARD;
|
s.majorstate = s.lastmajorstate = MAJORSTATE_DISCARD;
|
||||||
s.minorstate = MINORSTATE_TEXT;
|
s.minorstate = MINORSTATE_TEXT;
|
||||||
s.lastchar = 0;
|
s.wordlen = 0;
|
||||||
#if WWW_CONF_FORMS
|
#if WWW_CONF_FORMS
|
||||||
s.formaction[0] = 0;
|
s.formaction[0] = 0;
|
||||||
#endif /* WWW_CONF_FORMS */
|
#endif /* WWW_CONF_FORMS */
|
||||||
|
@ -305,10 +300,10 @@ do_word(void)
|
||||||
{
|
{
|
||||||
if(s.wordlen > 0) {
|
if(s.wordlen > 0) {
|
||||||
if(s.majorstate == MAJORSTATE_LINK) {
|
if(s.majorstate == MAJORSTATE_LINK) {
|
||||||
if(s.word[s.wordlen] != ISO_space) {
|
if(s.word[s.wordlen - 1] != ISO_space) {
|
||||||
add_char(ISO_space);
|
add_char(ISO_space);
|
||||||
}
|
}
|
||||||
} else if(s.majorstate == MAJORSTATE_DISCARD) {
|
} else if(s.majorstate >= MAJORSTATE_DISCARD) {
|
||||||
s.wordlen = 0;
|
s.wordlen = 0;
|
||||||
} else {
|
} else {
|
||||||
s.word[s.wordlen] = '\0';
|
s.word[s.wordlen] = '\0';
|
||||||
|
@ -368,13 +363,19 @@ static void
|
||||||
parse_tag(void)
|
parse_tag(void)
|
||||||
{
|
{
|
||||||
static char *tagattrparam;
|
static char *tagattrparam;
|
||||||
|
static unsigned char tag;
|
||||||
static unsigned char size;
|
static unsigned char size;
|
||||||
|
|
||||||
static char dummy;
|
tag = find_tag(s.tag);
|
||||||
|
/* If we are inside a <script> we mustn't interpret any tags
|
||||||
|
(inside JavaScript strings) but wait for the </script>. */
|
||||||
|
if(s.majorstate == MAJORSTATE_SCRIPT && tag != TAG_SLASHSCRIPT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PRINTF(("Parsing tag '%s' '%s' '%s'\n", s.tag, s.tagattr, s.tagattrparam));
|
PRINTF(("Parsing tag '%s' '%s' '%s'\n", s.tag, s.tagattr, s.tagattrparam));
|
||||||
|
|
||||||
switch(find_tag(s.tag)) {
|
switch(tag) {
|
||||||
case TAG_P:
|
case TAG_P:
|
||||||
case TAG_H1:
|
case TAG_H1:
|
||||||
case TAG_H2:
|
case TAG_H2:
|
||||||
|
@ -386,15 +387,18 @@ parse_tag(void)
|
||||||
case TAG_TR:
|
case TAG_TR:
|
||||||
case TAG_SLASHDIV:
|
case TAG_SLASHDIV:
|
||||||
case TAG_SLASHH:
|
case TAG_SLASHH:
|
||||||
dummy = 0;
|
|
||||||
newline();
|
newline();
|
||||||
break;
|
break;
|
||||||
case TAG_LI:
|
case TAG_LI:
|
||||||
|
if(s.tagattr[0] == 0) {
|
||||||
newline();
|
newline();
|
||||||
add_char(ISO_asterisk);
|
add_char(ISO_asterisk);
|
||||||
add_char(ISO_space);
|
add_char(ISO_space);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TAG_SCRIPT:
|
case TAG_SCRIPT:
|
||||||
|
switch_majorstate(MAJORSTATE_SCRIPT);
|
||||||
|
break;
|
||||||
case TAG_STYLE:
|
case TAG_STYLE:
|
||||||
case TAG_SELECT:
|
case TAG_SELECT:
|
||||||
switch_majorstate(MAJORSTATE_DISCARD);
|
switch_majorstate(MAJORSTATE_DISCARD);
|
||||||
|
@ -408,18 +412,6 @@ parse_tag(void)
|
||||||
case TAG_BODY:
|
case TAG_BODY:
|
||||||
s.majorstate = s.lastmajorstate = MAJORSTATE_BODY;
|
s.majorstate = s.lastmajorstate = MAJORSTATE_BODY;
|
||||||
break;
|
break;
|
||||||
case TAG_FRAME:
|
|
||||||
if(strncmp(s.tagattr, html_src, sizeof(html_src)) == 0 && s.tagattrparam[0] != 0) {
|
|
||||||
switch_majorstate(MAJORSTATE_BODY);
|
|
||||||
newline();
|
|
||||||
add_char(ISO_rbrack);
|
|
||||||
do_word();
|
|
||||||
htmlparser_link((char *)html_frame, (unsigned char)strlen(html_frame), s.tagattrparam);
|
|
||||||
PRINTF(("Frame [%s]\n", s.tagattrparam));
|
|
||||||
add_char(ISO_lbrack);
|
|
||||||
newline();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TAG_IMG:
|
case TAG_IMG:
|
||||||
if(strncmp(s.tagattr, html_alt, sizeof(html_alt)) == 0 && s.tagattrparam[0] != 0) {
|
if(strncmp(s.tagattr, html_alt, sizeof(html_alt)) == 0 && s.tagattrparam[0] != 0) {
|
||||||
add_char(ISO_lt);
|
add_char(ISO_lt);
|
||||||
|
@ -572,6 +564,15 @@ parse_word(char *data, uint8_t dlen)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MINORSTATE_TAG:
|
case MINORSTATE_TAG:
|
||||||
|
/* If we are inside a <srcipt> we mustn't mistake a JavaScript
|
||||||
|
equation with a '<' as a tag. So we check for the very next
|
||||||
|
character to be a '/' as we're only interested in parsing
|
||||||
|
the </script>. */
|
||||||
|
if(s.majorstate == MAJORSTATE_SCRIPT && data[0] != ISO_slash) {
|
||||||
|
s.minorstate = MINORSTATE_TEXT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* We are currently parsing within the name of a tag. We check
|
/* We are currently parsing within the name of a tag. We check
|
||||||
for the end of a tag (the '>' character) or whitespace (which
|
for the end of a tag (the '>' character) or whitespace (which
|
||||||
indicates that we should parse a tag attr argument
|
indicates that we should parse a tag attr argument
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
http_http "http://"
|
http_http "http://"
|
||||||
|
http_https "https://"
|
||||||
http_200 "200 "
|
http_200 "200 "
|
||||||
http_301 "301 "
|
http_301 "301 "
|
||||||
http_302 "302 "
|
http_302 "302 "
|
||||||
|
@ -10,3 +11,4 @@ http_location "location: "
|
||||||
http_host "Host: "
|
http_host "Host: "
|
||||||
http_crnl "\r\n"
|
http_crnl "\r\n"
|
||||||
http_html ".html"
|
http_html ".html"
|
||||||
|
http_redirect "<body>Redirect to "
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
const char http_http[8] =
|
const char http_http[8] =
|
||||||
/* "http://" */
|
/* "http://" */
|
||||||
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
|
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
|
||||||
|
const char http_https[9] =
|
||||||
|
/* "https://" */
|
||||||
|
{0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, };
|
||||||
const char http_200[5] =
|
const char http_200[5] =
|
||||||
/* "200 " */
|
/* "200 " */
|
||||||
{0x32, 0x30, 0x30, 0x20, };
|
{0x32, 0x30, 0x30, 0x20, };
|
||||||
|
@ -34,3 +37,6 @@ const char http_crnl[3] =
|
||||||
const char http_html[6] =
|
const char http_html[6] =
|
||||||
/* ".html" */
|
/* ".html" */
|
||||||
{0x2e, 0x68, 0x74, 0x6d, 0x6c, };
|
{0x2e, 0x68, 0x74, 0x6d, 0x6c, };
|
||||||
|
const char http_redirect[19] =
|
||||||
|
/* "<body>Redirect to " */
|
||||||
|
{0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, };
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
extern const char http_http[8];
|
extern const char http_http[8];
|
||||||
|
extern const char http_https[9];
|
||||||
extern const char http_200[5];
|
extern const char http_200[5];
|
||||||
extern const char http_301[5];
|
extern const char http_301[5];
|
||||||
extern const char http_302[5];
|
extern const char http_302[5];
|
||||||
|
@ -10,3 +11,4 @@ extern const char http_location[11];
|
||||||
extern const char http_host[7];
|
extern const char http_host[7];
|
||||||
extern const char http_crnl[3];
|
extern const char http_crnl[3];
|
||||||
extern const char http_html[6];
|
extern const char http_html[6];
|
||||||
|
extern const char http_redirect[19];
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
#define HTTPFLAG_NONE 0
|
#define HTTPFLAG_NONE 0
|
||||||
#define HTTPFLAG_OK 1
|
#define HTTPFLAG_OK 1
|
||||||
#define HTTPFLAG_MOVED 2
|
#define HTTPFLAG_MOVED 2
|
||||||
#define HTTPFLAG_ERROR 3
|
#define HTTPFLAG_HTTPS 3
|
||||||
|
|
||||||
|
|
||||||
#define ISO_nl 0x0a
|
#define ISO_nl 0x0a
|
||||||
|
@ -63,11 +63,11 @@ struct webclient_state {
|
||||||
|
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
char host[40];
|
char host[40];
|
||||||
char file[WWW_CONF_MAX_URLLEN];
|
char file[WWW_CONF_MAX_URLLEN - 10]; // URL - "http://<host>/"
|
||||||
uint16_t getrequestptr;
|
uint16_t getrequestptr;
|
||||||
uint16_t getrequestleft;
|
uint16_t getrequestleft;
|
||||||
|
|
||||||
char httpheaderline[200];
|
char httpheaderline[WWW_CONF_MAX_URLLEN + 10]; // URL + "Location: "
|
||||||
uint16_t httpheaderlineptr;
|
uint16_t httpheaderlineptr;
|
||||||
|
|
||||||
char mimetype[32];
|
char mimetype[32];
|
||||||
|
@ -327,13 +327,12 @@ parse_headers(uint16_t len)
|
||||||
char *cptr;
|
char *cptr;
|
||||||
static unsigned char i;
|
static unsigned char i;
|
||||||
|
|
||||||
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
|
while(len > 0) {
|
||||||
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
|
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
|
||||||
uip_appdata = (char *)uip_appdata + 1;
|
uip_appdata = (char *)uip_appdata + 1;
|
||||||
--len;
|
--len;
|
||||||
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
|
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
|
||||||
/* We have an entire HTTP header line in s.httpheaderline, so
|
/* We reached the end of an HTTP header line. */
|
||||||
we parse it. */
|
|
||||||
if(s.httpheaderline[0] == ISO_cr) {
|
if(s.httpheaderline[0] == ISO_cr) {
|
||||||
/* This was the last header line (i.e., and empty "\r\n"), so
|
/* This was the last header line (i.e., and empty "\r\n"), so
|
||||||
we are done with the headers and proceed with the actual
|
we are done with the headers and proceed with the actual
|
||||||
|
@ -342,6 +341,9 @@ parse_headers(uint16_t len)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) {
|
||||||
|
/* We have an entire HTTP header line in s.httpheaderline, so
|
||||||
|
we parse it. */
|
||||||
s.httpheaderline[s.httpheaderlineptr - 1] = 0;
|
s.httpheaderline[s.httpheaderlineptr - 1] = 0;
|
||||||
/* Check for specific HTTP header fields. */
|
/* Check for specific HTTP header fields. */
|
||||||
if(casecmp(s.httpheaderline, http_content_type,
|
if(casecmp(s.httpheaderline, http_content_type,
|
||||||
|
@ -358,7 +360,9 @@ parse_headers(uint16_t len)
|
||||||
cptr = s.httpheaderline +
|
cptr = s.httpheaderline +
|
||||||
sizeof(http_location) - 1;
|
sizeof(http_location) - 1;
|
||||||
|
|
||||||
if(strncmp(cptr, http_http, 7) == 0) {
|
if(strncmp(cptr, http_https, sizeof(http_https) - 1) == 0) {
|
||||||
|
s.httpflag = HTTPFLAG_HTTPS;
|
||||||
|
} else if(strncmp(cptr, http_http, 7) == 0) {
|
||||||
cptr += 7;
|
cptr += 7;
|
||||||
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
|
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
|
||||||
if(*cptr == 0 ||
|
if(*cptr == 0 ||
|
||||||
|
@ -375,15 +379,17 @@ parse_headers(uint16_t len)
|
||||||
strncpy(s.file, cptr, sizeof(s.file));
|
strncpy(s.file, cptr, sizeof(s.file));
|
||||||
/* s.file[s.httpheaderlineptr - i] = 0;*/
|
/* s.file[s.httpheaderlineptr - i] = 0;*/
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* We're done parsing, so we reset the pointer and start the
|
/* We're done parsing, so we reset the pointer and start the
|
||||||
next line. */
|
next line. */
|
||||||
s.httpheaderlineptr = 0;
|
s.httpheaderlineptr = 0;
|
||||||
} else {
|
} else {
|
||||||
|
if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) {
|
||||||
++s.httpheaderlineptr;
|
++s.httpheaderlineptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -403,7 +409,7 @@ newdata(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
|
if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
|
||||||
s.httpflag != HTTPFLAG_MOVED) {
|
s.httpflag == HTTPFLAG_OK) {
|
||||||
webclient_datahandler((char *)uip_appdata, len);
|
webclient_datahandler((char *)uip_appdata, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,7 +447,6 @@ webclient_appcall(void *state)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The acked() and newdata() functions may alter the uip_appdata
|
/* The acked() and newdata() functions may alter the uip_appdata
|
||||||
ptr, so we need to store it in the "dataptr" variable so that we
|
ptr, so we need to store it in the "dataptr" variable so that we
|
||||||
can restore it before the senddata() function is called. */
|
can restore it before the senddata() function is called. */
|
||||||
|
@ -474,10 +479,18 @@ webclient_appcall(void *state)
|
||||||
|
|
||||||
if(uip_closed()) {
|
if(uip_closed()) {
|
||||||
tcp_markconn(uip_conn, NULL);
|
tcp_markconn(uip_conn, NULL);
|
||||||
if(s.httpflag != HTTPFLAG_MOVED) {
|
switch(s.httpflag) {
|
||||||
|
case HTTPFLAG_HTTPS:
|
||||||
|
/* Send some info to the user. */
|
||||||
|
webclient_datahandler((char *)http_redirect, sizeof(http_redirect) - 1);
|
||||||
|
webclient_datahandler(s.file, strlen(s.file));
|
||||||
|
webclient_datahandler((char *)http_crnl, sizeof(http_crnl) - 1);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case HTTPFLAG_OK:
|
||||||
/* Send NULL data to signal EOF. */
|
/* Send NULL data to signal EOF. */
|
||||||
webclient_datahandler(NULL, 0);
|
webclient_datahandler(NULL, 0);
|
||||||
} else {
|
break;
|
||||||
|
case HTTPFLAG_MOVED:
|
||||||
/* conn = uip_connect(uip_conn->ripaddr, s.port);
|
/* conn = uip_connect(uip_conn->ripaddr, s.port);
|
||||||
if(conn != NULL) {
|
if(conn != NULL) {
|
||||||
dispatcher_markconn(conn, NULL);
|
dispatcher_markconn(conn, NULL);
|
||||||
|
@ -489,6 +502,7 @@ webclient_appcall(void *state)
|
||||||
}
|
}
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
webclient_get(s.host, s.port, s.file);
|
webclient_get(s.host, s.port, s.file);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ static struct ctk_button wgetyesbutton =
|
||||||
#if WWW_CONF_HISTORY_SIZE > 0
|
#if WWW_CONF_HISTORY_SIZE > 0
|
||||||
/* The char arrays that hold the history of visited URLs. */
|
/* The char arrays that hold the history of visited URLs. */
|
||||||
static char history[WWW_CONF_HISTORY_SIZE][WWW_CONF_MAX_URLLEN];
|
static char history[WWW_CONF_HISTORY_SIZE][WWW_CONF_MAX_URLLEN];
|
||||||
static char history_last;
|
static unsigned char history_last;
|
||||||
#endif /* WWW_CONF_HISTORY_SIZE > 0 */
|
#endif /* WWW_CONF_HISTORY_SIZE > 0 */
|
||||||
|
|
||||||
struct linkattrib {
|
struct linkattrib {
|
||||||
|
@ -170,6 +170,7 @@ static struct inputattrib *currptr;
|
||||||
|
|
||||||
#define ISO_nl 0x0a
|
#define ISO_nl 0x0a
|
||||||
#define ISO_space 0x20
|
#define ISO_space 0x20
|
||||||
|
#define ISO_hash 0x23
|
||||||
#define ISO_ampersand 0x26
|
#define ISO_ampersand 0x26
|
||||||
#define ISO_plus 0x2b
|
#define ISO_plus 0x2b
|
||||||
#define ISO_slash 0x2f
|
#define ISO_slash 0x2f
|
||||||
|
@ -181,6 +182,7 @@ static char *webpageptr;
|
||||||
static unsigned char x, y;
|
static unsigned char x, y;
|
||||||
static unsigned char loading;
|
static unsigned char loading;
|
||||||
static unsigned short firsty, pagey;
|
static unsigned short firsty, pagey;
|
||||||
|
static unsigned char newlines;
|
||||||
|
|
||||||
static unsigned char count;
|
static unsigned char count;
|
||||||
static char receivingmsgs[4][23] = {
|
static char receivingmsgs[4][23] = {
|
||||||
|
@ -194,7 +196,7 @@ PROCESS(www_process, "Web browser");
|
||||||
|
|
||||||
AUTOSTART_PROCESSES(&www_process);
|
AUTOSTART_PROCESSES(&www_process);
|
||||||
|
|
||||||
static void CC_FASTCALL formsubmit(struct formattrib *form);
|
static void CC_FASTCALL formsubmit(struct inputattrib *trigger);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* make_window()
|
/* make_window()
|
||||||
|
@ -277,6 +279,7 @@ start_loading(void)
|
||||||
loading = 1;
|
loading = 1;
|
||||||
x = y = 0;
|
x = y = 0;
|
||||||
pagey = 0;
|
pagey = 0;
|
||||||
|
newlines = 0;
|
||||||
webpageptr = webpage;
|
webpageptr = webpage;
|
||||||
|
|
||||||
clear_page();
|
clear_page();
|
||||||
|
@ -305,10 +308,13 @@ open_url(void)
|
||||||
static uip_ipaddr_t addr;
|
static uip_ipaddr_t addr;
|
||||||
|
|
||||||
/* Trim off any spaces in the end of the url. */
|
/* Trim off any spaces in the end of the url. */
|
||||||
urlptr = url + strlen(url) - 1;
|
urlptr = url + strlen(url);
|
||||||
while(*urlptr == ' ' && urlptr > url) {
|
while(urlptr > url) {
|
||||||
*urlptr = 0;
|
if(*(urlptr - 1) == ' ') {
|
||||||
--urlptr;
|
*--urlptr = 0;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't even try to go further if the URL is empty. */
|
/* Don't even try to go further if the URL is empty. */
|
||||||
|
@ -376,7 +382,6 @@ open_url(void)
|
||||||
} else {
|
} else {
|
||||||
show_statustext("Connecting...");
|
show_statustext("Connecting...");
|
||||||
}
|
}
|
||||||
redraw_window();
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* set_link(link):
|
/* set_link(link):
|
||||||
|
@ -510,15 +515,17 @@ PROCESS_THREAD(www_process, ev, data)
|
||||||
firsty = 0;
|
firsty = 0;
|
||||||
start_loading();
|
start_loading();
|
||||||
--history_last;
|
--history_last;
|
||||||
|
/* Note: history_last is unsigned ! */
|
||||||
if(history_last > WWW_CONF_HISTORY_SIZE) {
|
if(history_last > WWW_CONF_HISTORY_SIZE) {
|
||||||
history_last = WWW_CONF_HISTORY_SIZE - 1;
|
history_last = WWW_CONF_HISTORY_SIZE - 1;
|
||||||
}
|
}
|
||||||
memcpy(url, history[(int)history_last], WWW_CONF_MAX_URLLEN);
|
memcpy(url, history[(int)history_last], WWW_CONF_MAX_URLLEN);
|
||||||
|
*history[(int)history_last] = 0;
|
||||||
open_url();
|
open_url();
|
||||||
CTK_WIDGET_FOCUS(&mainwindow, &backbutton);
|
CTK_WIDGET_FOCUS(&mainwindow, &backbutton);
|
||||||
#endif /* WWW_CONF_HISTORY_SIZE > 0 */
|
#endif /* WWW_CONF_HISTORY_SIZE > 0 */
|
||||||
} else if(w == (struct ctk_widget *)&downbutton) {
|
} else if(w == (struct ctk_widget *)&downbutton) {
|
||||||
firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 4;
|
firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 2;
|
||||||
start_loading();
|
start_loading();
|
||||||
open_url();
|
open_url();
|
||||||
CTK_WIDGET_FOCUS(&mainwindow, &downbutton);
|
CTK_WIDGET_FOCUS(&mainwindow, &downbutton);
|
||||||
|
@ -557,9 +564,8 @@ PROCESS_THREAD(www_process, ev, data)
|
||||||
#if WWW_CONF_FORMS
|
#if WWW_CONF_FORMS
|
||||||
} else {
|
} else {
|
||||||
/* Assume form widget. */
|
/* Assume form widget. */
|
||||||
struct inputattrib *input = (struct inputattrib *)
|
formsubmit((struct inputattrib *)
|
||||||
(((char *)w) - offsetof(struct inputattrib, widget));
|
(((char *)w) - offsetof(struct inputattrib, widget)));
|
||||||
formsubmit(input->formptr);
|
|
||||||
#endif /* WWW_CONF_FORMS */
|
#endif /* WWW_CONF_FORMS */
|
||||||
}
|
}
|
||||||
} else if(ev == ctk_signal_hyperlink_activate) {
|
} else if(ev == ctk_signal_hyperlink_activate) {
|
||||||
|
@ -670,8 +676,6 @@ webclient_connected(void)
|
||||||
{
|
{
|
||||||
start_loading();
|
start_loading();
|
||||||
|
|
||||||
clear_page();
|
|
||||||
|
|
||||||
show_statustext("Request sent...");
|
show_statustext("Request sent...");
|
||||||
set_url(webclient_hostname(), webclient_port(), webclient_filename());
|
set_url(webclient_hostname(), webclient_port(), webclient_filename());
|
||||||
|
|
||||||
|
@ -731,6 +735,8 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type,
|
||||||
char *wptr;
|
char *wptr;
|
||||||
static unsigned char maxwidth;
|
static unsigned char maxwidth;
|
||||||
|
|
||||||
|
newlines = 0;
|
||||||
|
|
||||||
if(!loading) {
|
if(!loading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -837,6 +843,10 @@ htmlparser_newline(void)
|
||||||
{
|
{
|
||||||
char *wptr;
|
char *wptr;
|
||||||
|
|
||||||
|
if(++newlines > 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(pagey < firsty) {
|
if(pagey < firsty) {
|
||||||
++pagey;
|
++pagey;
|
||||||
x = 0;
|
x = 0;
|
||||||
|
@ -863,6 +873,8 @@ htmlparser_newline(void)
|
||||||
void
|
void
|
||||||
htmlparser_word(char *word, unsigned char wordlen)
|
htmlparser_word(char *word, unsigned char wordlen)
|
||||||
{
|
{
|
||||||
|
newlines = 0;
|
||||||
|
|
||||||
if(loading) {
|
if(loading) {
|
||||||
if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) {
|
if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) {
|
||||||
htmlparser_newline();
|
htmlparser_newline();
|
||||||
|
@ -886,7 +898,12 @@ htmlparser_word(char *word, unsigned char wordlen)
|
||||||
void
|
void
|
||||||
htmlparser_link(char *text, unsigned char textlen, char *url)
|
htmlparser_link(char *text, unsigned char textlen, char *url)
|
||||||
{
|
{
|
||||||
|
/* No link for https or fragment-only as we would't be able to handle it anyway. */
|
||||||
|
if(url[0] == ISO_hash || strncmp(url, http_https, sizeof(http_https) - 1) == 0) {
|
||||||
|
htmlparser_word(text, textlen);
|
||||||
|
} else {
|
||||||
add_pagewidget(text, textlen, url, CTK_WIDGET_HYPERLINK, 0);
|
add_pagewidget(text, textlen, url, CTK_WIDGET_HYPERLINK, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
#if WWW_CONF_FORMS
|
#if WWW_CONF_FORMS
|
||||||
|
@ -946,23 +963,36 @@ add_query(char delimiter, char *string)
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static void CC_FASTCALL
|
static void CC_FASTCALL
|
||||||
formsubmit(struct formattrib *form)
|
formsubmit(struct inputattrib *trigger)
|
||||||
{
|
{
|
||||||
struct inputattrib *inputptr;
|
struct inputattrib *input;
|
||||||
|
struct formattrib *form = trigger->formptr;
|
||||||
char delimiter = ISO_questionmark;
|
char delimiter = ISO_questionmark;
|
||||||
|
|
||||||
set_link(form->action);
|
set_link(form->action);
|
||||||
|
|
||||||
for(inputptr = form->nextptr; inputptr != NULL; inputptr = inputptr->nextptr) {
|
/* No button pressed so prepare to look for default button. */
|
||||||
|
if(trigger->widget.type == CTK_WIDGET_TEXTENTRY) {
|
||||||
|
trigger = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(input = form->nextptr; input != NULL; input = input->nextptr) {
|
||||||
char *name;
|
char *name;
|
||||||
char *value;
|
char *value;
|
||||||
|
|
||||||
if(inputptr->widget.type == CTK_WIDGET_BUTTON) {
|
if(input->widget.type == CTK_WIDGET_TEXTENTRY) {
|
||||||
name = ((struct submitattrib *)inputptr)->name;
|
name = ((struct textattrib *)input)->name;
|
||||||
value = ((struct submitattrib *)inputptr)->button.text;
|
value = ((struct textattrib *)input)->textentry.text;
|
||||||
} else {
|
} else {
|
||||||
name = ((struct textattrib *)inputptr)->name;
|
/* Consider first button as default button. */
|
||||||
value = ((struct textattrib *)inputptr)->textentry.text;
|
if(trigger == NULL) {
|
||||||
|
trigger = input;
|
||||||
|
}
|
||||||
|
if(input != trigger) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
name = ((struct submitattrib *)input)->name;
|
||||||
|
value = ((struct submitattrib *)input)->button.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_query(delimiter, name);
|
add_query(delimiter, name);
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#define WWW_CONF_HISTORY_SIZE 10
|
#define WWW_CONF_HISTORY_SIZE 10
|
||||||
#endif
|
#endif
|
||||||
#ifndef WWW_CONF_MAX_URLLEN
|
#ifndef WWW_CONF_MAX_URLLEN
|
||||||
#define WWW_CONF_MAX_URLLEN 300
|
#define WWW_CONF_MAX_URLLEN 255
|
||||||
#endif
|
#endif
|
||||||
#ifndef WWW_CONF_PAGEATTRIB_SIZE
|
#ifndef WWW_CONF_PAGEATTRIB_SIZE
|
||||||
#define WWW_CONF_PAGEATTRIB_SIZE 2000
|
#define WWW_CONF_PAGEATTRIB_SIZE 2000
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
http_http "http://"
|
http_http "http://"
|
||||||
|
http_https "https://"
|
||||||
http_200 "200 "
|
http_200 "200 "
|
||||||
http_301 "301 "
|
http_301 "301 "
|
||||||
http_302 "302 "
|
http_302 "302 "
|
||||||
|
@ -32,4 +33,4 @@ http_gif ".gif"
|
||||||
http_jpg ".jpg"
|
http_jpg ".jpg"
|
||||||
http_text ".text"
|
http_text ".text"
|
||||||
http_txt ".txt"
|
http_txt ".txt"
|
||||||
|
http_redirect "<body>Redirect to "
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
const char http_http[8] =
|
const char http_http[8] =
|
||||||
/* "http://" */
|
/* "http://" */
|
||||||
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
|
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
|
||||||
|
const char http_https[9] =
|
||||||
|
/* "https://" */
|
||||||
|
{0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, };
|
||||||
const char http_200[5] =
|
const char http_200[5] =
|
||||||
/* "200 " */
|
/* "200 " */
|
||||||
{0x32, 0x30, 0x30, 0x20, };
|
{0x32, 0x30, 0x30, 0x20, };
|
||||||
|
@ -100,3 +103,6 @@ const char http_text[6] =
|
||||||
const char http_txt[5] =
|
const char http_txt[5] =
|
||||||
/* ".txt" */
|
/* ".txt" */
|
||||||
{0x2e, 0x74, 0x78, 0x74, };
|
{0x2e, 0x74, 0x78, 0x74, };
|
||||||
|
const char http_redirect[19] =
|
||||||
|
/* "<body>Redirect to " */
|
||||||
|
{0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, };
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
extern const char http_http[8];
|
extern const char http_http[8];
|
||||||
|
extern const char http_https[9];
|
||||||
extern const char http_200[5];
|
extern const char http_200[5];
|
||||||
extern const char http_301[5];
|
extern const char http_301[5];
|
||||||
extern const char http_302[5];
|
extern const char http_302[5];
|
||||||
|
@ -32,3 +33,4 @@ extern const char http_gif[5];
|
||||||
extern const char http_jpg[5];
|
extern const char http_jpg[5];
|
||||||
extern const char http_text[6];
|
extern const char http_text[6];
|
||||||
extern const char http_txt[5];
|
extern const char http_txt[5];
|
||||||
|
extern const char http_redirect[19];
|
||||||
|
|
|
@ -72,7 +72,6 @@ typedef unsigned short uip_stats_t;
|
||||||
#define UIP_CONF_LLH_LEN 14
|
#define UIP_CONF_LLH_LEN 14
|
||||||
#define RESOLV_CONF_SUPPORTS_MDNS 0
|
#define RESOLV_CONF_SUPPORTS_MDNS 0
|
||||||
#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0
|
#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0
|
||||||
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 1
|
|
||||||
|
|
||||||
#define LOADER_CONF_ARCH "lib/unload.h"
|
#define LOADER_CONF_ARCH "lib/unload.h"
|
||||||
|
|
||||||
|
|
|
@ -56,11 +56,8 @@ typedef long s32_t;
|
||||||
|
|
||||||
typedef unsigned short uip_stats_t;
|
typedef unsigned short uip_stats_t;
|
||||||
|
|
||||||
#define UIP_CONF_MAX_CONNECTIONS 40
|
|
||||||
#define UIP_CONF_MAX_LISTENPORTS 40
|
|
||||||
#define UIP_CONF_LLH_LEN 14
|
#define UIP_CONF_LLH_LEN 14
|
||||||
#define UIP_CONF_BUFFER_SIZE 1514
|
#define UIP_CONF_BUFFER_SIZE 1514
|
||||||
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
|
|
||||||
#define UIP_CONF_TCP_SPLIT 1
|
#define UIP_CONF_TCP_SPLIT 1
|
||||||
#define UIP_CONF_LOGGING 1
|
#define UIP_CONF_LOGGING 1
|
||||||
#define UIP_CONF_UDP_CHECKSUMS 1
|
#define UIP_CONF_UDP_CHECKSUMS 1
|
||||||
|
@ -77,6 +74,8 @@ typedef unsigned short uip_stats_t;
|
||||||
#define UIP_CONF_IP_FORWARD 1
|
#define UIP_CONF_IP_FORWARD 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RESOLV_CONF_SUPPORTS_MDNS 0
|
||||||
|
#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#define ctk_arch_isprint isprint
|
#define ctk_arch_isprint isprint
|
||||||
|
|
Loading…
Reference in a new issue