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_br "br\0"
|
||||
html_form "form\0"
|
||||
html_frame "frame\0"
|
||||
html_h1 "h1\0"
|
||||
html_h2 "h2\0"
|
||||
html_h3 "h3\0"
|
||||
|
|
|
@ -31,9 +31,6 @@ const char html_br[4] =
|
|||
const char html_form[6] =
|
||||
/* "form\0" */
|
||||
{0x66, 0x6f, 0x72, 0x6d, 00, };
|
||||
const char html_frame[7] =
|
||||
/* "frame\0" */
|
||||
{0x66, 0x72, 0x61, 0x6d, 0x65, 00, };
|
||||
const char html_h1[4] =
|
||||
/* "h1\0" */
|
||||
{0x68, 0x31, 00, };
|
||||
|
|
|
@ -9,7 +9,6 @@ extern const char html_a[3];
|
|||
extern const char html_body[6];
|
||||
extern const char html_br[4];
|
||||
extern const char html_form[6];
|
||||
extern const char html_frame[7];
|
||||
extern const char html_h1[4];
|
||||
extern const char html_h2[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_gt 0x3e
|
||||
|
||||
#define ISO_rbrack 0x5b
|
||||
#define ISO_lbrack 0x5d
|
||||
|
||||
#define MINORSTATE_NONE 0
|
||||
#define MINORSTATE_TEXT 1 /* Parse normal text */
|
||||
#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_FORM 3
|
||||
#define MAJORSTATE_DISCARD 4
|
||||
|
||||
#define MAJORSTATE_SCRIPT 5
|
||||
|
||||
struct htmlparser_state {
|
||||
|
||||
|
@ -151,7 +148,7 @@ struct htmlparser_state {
|
|||
unsigned char tagattrptr;
|
||||
char tagattrparam[WWW_CONF_MAX_URLLEN + 1];
|
||||
unsigned char tagattrparamptr;
|
||||
unsigned char lastchar, quotechar;
|
||||
unsigned char quotechar;
|
||||
unsigned char majorstate, lastmajorstate;
|
||||
char linkurl[WWW_CONF_MAX_URLLEN + 1];
|
||||
|
||||
|
@ -196,33 +193,31 @@ static const char *tags[] = {
|
|||
html_br,
|
||||
#define TAG_FORM 10
|
||||
html_form,
|
||||
#define TAG_FRAME 11
|
||||
html_frame,
|
||||
#define TAG_H1 12
|
||||
#define TAG_H1 11
|
||||
html_h1,
|
||||
#define TAG_H2 13
|
||||
#define TAG_H2 12
|
||||
html_h2,
|
||||
#define TAG_H3 14
|
||||
#define TAG_H3 13
|
||||
html_h3,
|
||||
#define TAG_H4 15
|
||||
#define TAG_H4 14
|
||||
html_h4,
|
||||
#define TAG_IMG 16
|
||||
#define TAG_IMG 15
|
||||
html_img,
|
||||
#define TAG_INPUT 17
|
||||
#define TAG_INPUT 16
|
||||
html_input,
|
||||
#define TAG_LI 18
|
||||
#define TAG_LI 17
|
||||
html_li,
|
||||
#define TAG_P 19
|
||||
#define TAG_P 18
|
||||
html_p,
|
||||
#define TAG_SCRIPT 20
|
||||
#define TAG_SCRIPT 19
|
||||
html_script,
|
||||
#define TAG_SELECT 21
|
||||
#define TAG_SELECT 20
|
||||
html_select,
|
||||
#define TAG_STYLE 22
|
||||
#define TAG_STYLE 21
|
||||
html_style,
|
||||
#define TAG_TR 23
|
||||
#define TAG_TR 22
|
||||
html_tr,
|
||||
#define TAG_LAST 24
|
||||
#define TAG_LAST 23
|
||||
last,
|
||||
};
|
||||
|
||||
|
@ -254,7 +249,7 @@ htmlparser_init(void)
|
|||
{
|
||||
s.majorstate = s.lastmajorstate = MAJORSTATE_DISCARD;
|
||||
s.minorstate = MINORSTATE_TEXT;
|
||||
s.lastchar = 0;
|
||||
s.wordlen = 0;
|
||||
#if WWW_CONF_FORMS
|
||||
s.formaction[0] = 0;
|
||||
#endif /* WWW_CONF_FORMS */
|
||||
|
@ -305,10 +300,10 @@ do_word(void)
|
|||
{
|
||||
if(s.wordlen > 0) {
|
||||
if(s.majorstate == MAJORSTATE_LINK) {
|
||||
if(s.word[s.wordlen] != ISO_space) {
|
||||
if(s.word[s.wordlen - 1] != ISO_space) {
|
||||
add_char(ISO_space);
|
||||
}
|
||||
} else if(s.majorstate == MAJORSTATE_DISCARD) {
|
||||
} else if(s.majorstate >= MAJORSTATE_DISCARD) {
|
||||
s.wordlen = 0;
|
||||
} else {
|
||||
s.word[s.wordlen] = '\0';
|
||||
|
@ -368,13 +363,19 @@ static void
|
|||
parse_tag(void)
|
||||
{
|
||||
static char *tagattrparam;
|
||||
static unsigned char tag;
|
||||
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));
|
||||
|
||||
switch(find_tag(s.tag)) {
|
||||
switch(tag) {
|
||||
case TAG_P:
|
||||
case TAG_H1:
|
||||
case TAG_H2:
|
||||
|
@ -386,15 +387,18 @@ parse_tag(void)
|
|||
case TAG_TR:
|
||||
case TAG_SLASHDIV:
|
||||
case TAG_SLASHH:
|
||||
dummy = 0;
|
||||
newline();
|
||||
break;
|
||||
case TAG_LI:
|
||||
newline();
|
||||
add_char(ISO_asterisk);
|
||||
add_char(ISO_space);
|
||||
if(s.tagattr[0] == 0) {
|
||||
newline();
|
||||
add_char(ISO_asterisk);
|
||||
add_char(ISO_space);
|
||||
}
|
||||
break;
|
||||
case TAG_SCRIPT:
|
||||
switch_majorstate(MAJORSTATE_SCRIPT);
|
||||
break;
|
||||
case TAG_STYLE:
|
||||
case TAG_SELECT:
|
||||
switch_majorstate(MAJORSTATE_DISCARD);
|
||||
|
@ -408,18 +412,6 @@ parse_tag(void)
|
|||
case TAG_BODY:
|
||||
s.majorstate = s.lastmajorstate = MAJORSTATE_BODY;
|
||||
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:
|
||||
if(strncmp(s.tagattr, html_alt, sizeof(html_alt)) == 0 && s.tagattrparam[0] != 0) {
|
||||
add_char(ISO_lt);
|
||||
|
@ -572,6 +564,15 @@ parse_word(char *data, uint8_t dlen)
|
|||
}
|
||||
break;
|
||||
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
|
||||
for the end of a tag (the '>' character) or whitespace (which
|
||||
indicates that we should parse a tag attr argument
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
http_http "http://"
|
||||
http_https "https://"
|
||||
http_200 "200 "
|
||||
http_301 "301 "
|
||||
http_302 "302 "
|
||||
|
@ -10,3 +11,4 @@ http_location "location: "
|
|||
http_host "Host: "
|
||||
http_crnl "\r\n"
|
||||
http_html ".html"
|
||||
http_redirect "<body>Redirect to "
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
const char http_http[8] =
|
||||
/* "http://" */
|
||||
{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] =
|
||||
/* "200 " */
|
||||
{0x32, 0x30, 0x30, 0x20, };
|
||||
|
@ -34,3 +37,6 @@ const char http_crnl[3] =
|
|||
const char http_html[6] =
|
||||
/* ".html" */
|
||||
{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_https[9];
|
||||
extern const char http_200[5];
|
||||
extern const char http_301[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_crnl[3];
|
||||
extern const char http_html[6];
|
||||
extern const char http_redirect[19];
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#define HTTPFLAG_NONE 0
|
||||
#define HTTPFLAG_OK 1
|
||||
#define HTTPFLAG_MOVED 2
|
||||
#define HTTPFLAG_ERROR 3
|
||||
#define HTTPFLAG_HTTPS 3
|
||||
|
||||
|
||||
#define ISO_nl 0x0a
|
||||
|
@ -63,11 +63,11 @@ struct webclient_state {
|
|||
|
||||
uint16_t port;
|
||||
char host[40];
|
||||
char file[WWW_CONF_MAX_URLLEN];
|
||||
char file[WWW_CONF_MAX_URLLEN - 10]; // URL - "http://<host>/"
|
||||
uint16_t getrequestptr;
|
||||
uint16_t getrequestleft;
|
||||
|
||||
char httpheaderline[200];
|
||||
char httpheaderline[WWW_CONF_MAX_URLLEN + 10]; // URL + "Location: "
|
||||
uint16_t httpheaderlineptr;
|
||||
|
||||
char mimetype[32];
|
||||
|
@ -327,13 +327,12 @@ parse_headers(uint16_t len)
|
|||
char *cptr;
|
||||
static unsigned char i;
|
||||
|
||||
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
|
||||
while(len > 0) {
|
||||
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
|
||||
uip_appdata = (char *)uip_appdata + 1;
|
||||
--len;
|
||||
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
|
||||
/* We have an entire HTTP header line in s.httpheaderline, so
|
||||
we parse it. */
|
||||
/* We reached the end of an HTTP header line. */
|
||||
if(s.httpheaderline[0] == ISO_cr) {
|
||||
/* This was the last header line (i.e., and empty "\r\n"), so
|
||||
we are done with the headers and proceed with the actual
|
||||
|
@ -342,46 +341,53 @@ parse_headers(uint16_t len)
|
|||
return len;
|
||||
}
|
||||
|
||||
s.httpheaderline[s.httpheaderlineptr - 1] = 0;
|
||||
/* Check for specific HTTP header fields. */
|
||||
if(casecmp(s.httpheaderline, http_content_type,
|
||||
sizeof(http_content_type) - 1) == 0) {
|
||||
/* Found Content-type field. */
|
||||
cptr = strchr(s.httpheaderline, ';');
|
||||
if(cptr != NULL) {
|
||||
*cptr = 0;
|
||||
}
|
||||
strncpy(s.mimetype, s.httpheaderline +
|
||||
sizeof(http_content_type) - 1, sizeof(s.mimetype));
|
||||
} else if(casecmp(s.httpheaderline, http_location,
|
||||
sizeof(http_location) - 1) == 0) {
|
||||
cptr = s.httpheaderline +
|
||||
sizeof(http_location) - 1;
|
||||
|
||||
if(strncmp(cptr, http_http, 7) == 0) {
|
||||
cptr += 7;
|
||||
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
|
||||
if(*cptr == 0 ||
|
||||
*cptr == '/' ||
|
||||
*cptr == ' ' ||
|
||||
*cptr == ':') {
|
||||
s.host[i] = 0;
|
||||
break;
|
||||
}
|
||||
s.host[i] = *cptr;
|
||||
++cptr;
|
||||
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;
|
||||
/* Check for specific HTTP header fields. */
|
||||
if(casecmp(s.httpheaderline, http_content_type,
|
||||
sizeof(http_content_type) - 1) == 0) {
|
||||
/* Found Content-type field. */
|
||||
cptr = strchr(s.httpheaderline, ';');
|
||||
if(cptr != NULL) {
|
||||
*cptr = 0;
|
||||
}
|
||||
}
|
||||
strncpy(s.file, cptr, sizeof(s.file));
|
||||
/* s.file[s.httpheaderlineptr - i] = 0;*/
|
||||
}
|
||||
strncpy(s.mimetype, s.httpheaderline +
|
||||
sizeof(http_content_type) - 1, sizeof(s.mimetype));
|
||||
} else if(casecmp(s.httpheaderline, http_location,
|
||||
sizeof(http_location) - 1) == 0) {
|
||||
cptr = s.httpheaderline +
|
||||
sizeof(http_location) - 1;
|
||||
|
||||
if(strncmp(cptr, http_https, sizeof(http_https) - 1) == 0) {
|
||||
s.httpflag = HTTPFLAG_HTTPS;
|
||||
} else if(strncmp(cptr, http_http, 7) == 0) {
|
||||
cptr += 7;
|
||||
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
|
||||
if(*cptr == 0 ||
|
||||
*cptr == '/' ||
|
||||
*cptr == ' ' ||
|
||||
*cptr == ':') {
|
||||
s.host[i] = 0;
|
||||
break;
|
||||
}
|
||||
s.host[i] = *cptr;
|
||||
++cptr;
|
||||
}
|
||||
}
|
||||
strncpy(s.file, cptr, sizeof(s.file));
|
||||
/* s.file[s.httpheaderlineptr - i] = 0;*/
|
||||
}
|
||||
}
|
||||
|
||||
/* We're done parsing, so we reset the pointer and start the
|
||||
next line. */
|
||||
s.httpheaderlineptr = 0;
|
||||
} else {
|
||||
++s.httpheaderlineptr;
|
||||
if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) {
|
||||
++s.httpheaderlineptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return len;
|
||||
|
@ -403,7 +409,7 @@ newdata(void)
|
|||
}
|
||||
|
||||
if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
|
||||
s.httpflag != HTTPFLAG_MOVED) {
|
||||
s.httpflag == HTTPFLAG_OK) {
|
||||
webclient_datahandler((char *)uip_appdata, len);
|
||||
}
|
||||
}
|
||||
|
@ -441,7 +447,6 @@ webclient_appcall(void *state)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/* The acked() and newdata() functions may alter the uip_appdata
|
||||
ptr, so we need to store it in the "dataptr" variable so that we
|
||||
can restore it before the senddata() function is called. */
|
||||
|
@ -474,10 +479,18 @@ webclient_appcall(void *state)
|
|||
|
||||
if(uip_closed()) {
|
||||
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. */
|
||||
webclient_datahandler(NULL, 0);
|
||||
} else {
|
||||
break;
|
||||
case HTTPFLAG_MOVED:
|
||||
/* conn = uip_connect(uip_conn->ripaddr, s.port);
|
||||
if(conn != NULL) {
|
||||
dispatcher_markconn(conn, NULL);
|
||||
|
@ -489,6 +502,7 @@ webclient_appcall(void *state)
|
|||
}
|
||||
#endif /* UIP_UDP */
|
||||
webclient_get(s.host, s.port, s.file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ static struct ctk_button wgetyesbutton =
|
|||
#if WWW_CONF_HISTORY_SIZE > 0
|
||||
/* The char arrays that hold the history of visited URLs. */
|
||||
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 */
|
||||
|
||||
struct linkattrib {
|
||||
|
@ -170,17 +170,19 @@ static struct inputattrib *currptr;
|
|||
|
||||
#define ISO_nl 0x0a
|
||||
#define ISO_space 0x20
|
||||
#define ISO_hash 0x23
|
||||
#define ISO_ampersand 0x26
|
||||
#define ISO_plus 0x2b
|
||||
#define ISO_plus 0x2b
|
||||
#define ISO_slash 0x2f
|
||||
#define ISO_eq 0x3d
|
||||
#define ISO_questionmark 0x3f
|
||||
#define ISO_questionmark 0x3f
|
||||
|
||||
/* The state of the rendering code. */
|
||||
static char *webpageptr;
|
||||
static unsigned char x, y;
|
||||
static unsigned char loading;
|
||||
static unsigned short firsty, pagey;
|
||||
static unsigned char newlines;
|
||||
|
||||
static unsigned char count;
|
||||
static char receivingmsgs[4][23] = {
|
||||
|
@ -194,7 +196,7 @@ PROCESS(www_process, "Web browser");
|
|||
|
||||
AUTOSTART_PROCESSES(&www_process);
|
||||
|
||||
static void CC_FASTCALL formsubmit(struct formattrib *form);
|
||||
static void CC_FASTCALL formsubmit(struct inputattrib *trigger);
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* make_window()
|
||||
|
@ -277,6 +279,7 @@ start_loading(void)
|
|||
loading = 1;
|
||||
x = y = 0;
|
||||
pagey = 0;
|
||||
newlines = 0;
|
||||
webpageptr = webpage;
|
||||
|
||||
clear_page();
|
||||
|
@ -305,10 +308,13 @@ open_url(void)
|
|||
static uip_ipaddr_t addr;
|
||||
|
||||
/* Trim off any spaces in the end of the url. */
|
||||
urlptr = url + strlen(url) - 1;
|
||||
while(*urlptr == ' ' && urlptr > url) {
|
||||
*urlptr = 0;
|
||||
--urlptr;
|
||||
urlptr = url + strlen(url);
|
||||
while(urlptr > url) {
|
||||
if(*(urlptr - 1) == ' ') {
|
||||
*--urlptr = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't even try to go further if the URL is empty. */
|
||||
|
@ -376,7 +382,6 @@ open_url(void)
|
|||
} else {
|
||||
show_statustext("Connecting...");
|
||||
}
|
||||
redraw_window();
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* set_link(link):
|
||||
|
@ -510,15 +515,17 @@ PROCESS_THREAD(www_process, ev, data)
|
|||
firsty = 0;
|
||||
start_loading();
|
||||
--history_last;
|
||||
/* Note: history_last is unsigned ! */
|
||||
if(history_last > WWW_CONF_HISTORY_SIZE) {
|
||||
history_last = WWW_CONF_HISTORY_SIZE - 1;
|
||||
}
|
||||
memcpy(url, history[(int)history_last], WWW_CONF_MAX_URLLEN);
|
||||
*history[(int)history_last] = 0;
|
||||
open_url();
|
||||
CTK_WIDGET_FOCUS(&mainwindow, &backbutton);
|
||||
#endif /* WWW_CONF_HISTORY_SIZE > 0 */
|
||||
} else if(w == (struct ctk_widget *)&downbutton) {
|
||||
firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 4;
|
||||
firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 2;
|
||||
start_loading();
|
||||
open_url();
|
||||
CTK_WIDGET_FOCUS(&mainwindow, &downbutton);
|
||||
|
@ -557,9 +564,8 @@ PROCESS_THREAD(www_process, ev, data)
|
|||
#if WWW_CONF_FORMS
|
||||
} else {
|
||||
/* Assume form widget. */
|
||||
struct inputattrib *input = (struct inputattrib *)
|
||||
(((char *)w) - offsetof(struct inputattrib, widget));
|
||||
formsubmit(input->formptr);
|
||||
formsubmit((struct inputattrib *)
|
||||
(((char *)w) - offsetof(struct inputattrib, widget)));
|
||||
#endif /* WWW_CONF_FORMS */
|
||||
}
|
||||
} else if(ev == ctk_signal_hyperlink_activate) {
|
||||
|
@ -670,8 +676,6 @@ webclient_connected(void)
|
|||
{
|
||||
start_loading();
|
||||
|
||||
clear_page();
|
||||
|
||||
show_statustext("Request sent...");
|
||||
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;
|
||||
static unsigned char maxwidth;
|
||||
|
||||
newlines = 0;
|
||||
|
||||
if(!loading) {
|
||||
return;
|
||||
}
|
||||
|
@ -770,49 +776,49 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type,
|
|||
wptr[size + border] = ' ';
|
||||
|
||||
switch(type) {
|
||||
case CTK_WIDGET_HYPERLINK: {
|
||||
struct linkattrib *linkptr =
|
||||
(struct linkattrib *)add_pageattrib(sizeof(struct linkattrib) /* incl 1 attrib char */ + attriblen);
|
||||
if(linkptr != NULL) {
|
||||
CTK_HYPERLINK_NEW(&linkptr->hyperlink, x, y + 3, size, wptr, linkptr->url);
|
||||
strcpy(linkptr->url, attrib);
|
||||
CTK_WIDGET_SET_FLAG(&linkptr->hyperlink, CTK_WIDGET_FLAG_MONOSPACE);
|
||||
CTK_WIDGET_ADD(&mainwindow, &linkptr->hyperlink);
|
||||
}
|
||||
break;
|
||||
case CTK_WIDGET_HYPERLINK: {
|
||||
struct linkattrib *linkptr =
|
||||
(struct linkattrib *)add_pageattrib(sizeof(struct linkattrib) /* incl 1 attrib char */ + attriblen);
|
||||
if(linkptr != NULL) {
|
||||
CTK_HYPERLINK_NEW(&linkptr->hyperlink, x, y + 3, size, wptr, linkptr->url);
|
||||
strcpy(linkptr->url, attrib);
|
||||
CTK_WIDGET_SET_FLAG(&linkptr->hyperlink, CTK_WIDGET_FLAG_MONOSPACE);
|
||||
CTK_WIDGET_ADD(&mainwindow, &linkptr->hyperlink);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if WWW_CONF_FORMS
|
||||
case CTK_WIDGET_BUTTON: {
|
||||
struct submitattrib *submitptr =
|
||||
(struct submitattrib *)add_pageattrib(sizeof(struct submitattrib) /* incl 1 attrib char */ + attriblen);
|
||||
if(submitptr != NULL) {
|
||||
CTK_BUTTON_NEW((struct ctk_button *)&submitptr->button, x, y + 3, size, wptr);
|
||||
add_forminput((struct inputattrib *)submitptr);
|
||||
submitptr->formptr = formptr;
|
||||
strcpy(submitptr->name, attrib);
|
||||
CTK_WIDGET_SET_FLAG(&submitptr->button, CTK_WIDGET_FLAG_MONOSPACE);
|
||||
CTK_WIDGET_ADD(&mainwindow, &submitptr->button);
|
||||
}
|
||||
break;
|
||||
case CTK_WIDGET_BUTTON: {
|
||||
struct submitattrib *submitptr =
|
||||
(struct submitattrib *)add_pageattrib(sizeof(struct submitattrib) /* incl 1 attrib char */ + attriblen);
|
||||
if(submitptr != NULL) {
|
||||
CTK_BUTTON_NEW((struct ctk_button *)&submitptr->button, x, y + 3, size, wptr);
|
||||
add_forminput((struct inputattrib *)submitptr);
|
||||
submitptr->formptr = formptr;
|
||||
strcpy(submitptr->name, attrib);
|
||||
CTK_WIDGET_SET_FLAG(&submitptr->button, CTK_WIDGET_FLAG_MONOSPACE);
|
||||
CTK_WIDGET_ADD(&mainwindow, &submitptr->button);
|
||||
}
|
||||
case CTK_WIDGET_TEXTENTRY: {
|
||||
struct textattrib *textptr =
|
||||
(struct textattrib *)add_pageattrib(sizeof(struct textattrib) /* incl 1 attrib char */ + attriblen
|
||||
+ (size ? WWW_CONF_MAX_INPUTVALUELEN : strlen(text)) + 1);
|
||||
if(textptr != NULL) {
|
||||
CTK_TEXTENTRY_NEW((struct ctk_textentry *)&textptr->textentry, x, y + 3, size, 1,
|
||||
textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN);
|
||||
add_forminput((struct inputattrib *)textptr);
|
||||
textptr->formptr = formptr;
|
||||
strcpy(textptr->textentry.text, text);
|
||||
strcpy(textptr->name, attrib);
|
||||
if(size) {
|
||||
CTK_WIDGET_SET_FLAG(&textptr->textentry, CTK_WIDGET_FLAG_MONOSPACE);
|
||||
CTK_WIDGET_ADD(&mainwindow, &textptr->textentry);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CTK_WIDGET_TEXTENTRY: {
|
||||
struct textattrib *textptr =
|
||||
(struct textattrib *)add_pageattrib(sizeof(struct textattrib) /* incl 1 attrib char */ + attriblen
|
||||
+ (size ? WWW_CONF_MAX_INPUTVALUELEN : strlen(text)) + 1);
|
||||
if(textptr != NULL) {
|
||||
CTK_TEXTENTRY_NEW((struct ctk_textentry *)&textptr->textentry, x, y + 3, size, 1,
|
||||
textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN);
|
||||
add_forminput((struct inputattrib *)textptr);
|
||||
textptr->formptr = formptr;
|
||||
strcpy(textptr->textentry.text, text);
|
||||
strcpy(textptr->name, attrib);
|
||||
if(size) {
|
||||
CTK_WIDGET_SET_FLAG(&textptr->textentry, CTK_WIDGET_FLAG_MONOSPACE);
|
||||
CTK_WIDGET_ADD(&mainwindow, &textptr->textentry);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* WWW_CONF_FORMS */
|
||||
}
|
||||
}
|
||||
|
@ -837,6 +843,10 @@ htmlparser_newline(void)
|
|||
{
|
||||
char *wptr;
|
||||
|
||||
if(++newlines > 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(pagey < firsty) {
|
||||
++pagey;
|
||||
x = 0;
|
||||
|
@ -863,6 +873,8 @@ htmlparser_newline(void)
|
|||
void
|
||||
htmlparser_word(char *word, unsigned char wordlen)
|
||||
{
|
||||
newlines = 0;
|
||||
|
||||
if(loading) {
|
||||
if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) {
|
||||
htmlparser_newline();
|
||||
|
@ -886,7 +898,12 @@ htmlparser_word(char *word, unsigned char wordlen)
|
|||
void
|
||||
htmlparser_link(char *text, unsigned char textlen, char *url)
|
||||
{
|
||||
add_pagewidget(text, textlen, url, CTK_WIDGET_HYPERLINK, 0);
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if WWW_CONF_FORMS
|
||||
|
@ -946,23 +963,36 @@ add_query(char delimiter, char *string)
|
|||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
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;
|
||||
|
||||
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 *value;
|
||||
|
||||
if(inputptr->widget.type == CTK_WIDGET_BUTTON) {
|
||||
name = ((struct submitattrib *)inputptr)->name;
|
||||
value = ((struct submitattrib *)inputptr)->button.text;
|
||||
if(input->widget.type == CTK_WIDGET_TEXTENTRY) {
|
||||
name = ((struct textattrib *)input)->name;
|
||||
value = ((struct textattrib *)input)->textentry.text;
|
||||
} else {
|
||||
name = ((struct textattrib *)inputptr)->name;
|
||||
value = ((struct textattrib *)inputptr)->textentry.text;
|
||||
/* Consider first button as default button. */
|
||||
if(trigger == NULL) {
|
||||
trigger = input;
|
||||
}
|
||||
if(input != trigger) {
|
||||
continue;
|
||||
}
|
||||
name = ((struct submitattrib *)input)->name;
|
||||
value = ((struct submitattrib *)input)->button.text;
|
||||
}
|
||||
|
||||
add_query(delimiter, name);
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#define WWW_CONF_HISTORY_SIZE 10
|
||||
#endif
|
||||
#ifndef WWW_CONF_MAX_URLLEN
|
||||
#define WWW_CONF_MAX_URLLEN 300
|
||||
#define WWW_CONF_MAX_URLLEN 255
|
||||
#endif
|
||||
#ifndef WWW_CONF_PAGEATTRIB_SIZE
|
||||
#define WWW_CONF_PAGEATTRIB_SIZE 2000
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
http_http "http://"
|
||||
http_https "https://"
|
||||
http_200 "200 "
|
||||
http_301 "301 "
|
||||
http_302 "302 "
|
||||
|
@ -32,4 +33,4 @@ http_gif ".gif"
|
|||
http_jpg ".jpg"
|
||||
http_text ".text"
|
||||
http_txt ".txt"
|
||||
|
||||
http_redirect "<body>Redirect to "
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
const char http_http[8] =
|
||||
/* "http://" */
|
||||
{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] =
|
||||
/* "200 " */
|
||||
{0x32, 0x30, 0x30, 0x20, };
|
||||
|
@ -100,3 +103,6 @@ const char http_text[6] =
|
|||
const char http_txt[5] =
|
||||
/* ".txt" */
|
||||
{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_https[9];
|
||||
extern const char http_200[5];
|
||||
extern const char http_301[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_text[6];
|
||||
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 RESOLV_CONF_SUPPORTS_MDNS 0
|
||||
#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0
|
||||
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 1
|
||||
|
||||
#define LOADER_CONF_ARCH "lib/unload.h"
|
||||
|
||||
|
|
|
@ -56,11 +56,8 @@ typedef long s32_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_BUFFER_SIZE 1514
|
||||
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
|
||||
#define UIP_CONF_TCP_SPLIT 1
|
||||
#define UIP_CONF_LOGGING 1
|
||||
#define UIP_CONF_UDP_CHECKSUMS 1
|
||||
|
@ -77,6 +74,8 @@ typedef unsigned short uip_stats_t;
|
|||
#define UIP_CONF_IP_FORWARD 1
|
||||
#endif
|
||||
|
||||
#define RESOLV_CONF_SUPPORTS_MDNS 0
|
||||
#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0
|
||||
|
||||
#include <ctype.h>
|
||||
#define ctk_arch_isprint isprint
|
||||
|
|
Loading…
Reference in a new issue