Bugfix: the web client previously implicitly depended on uip_buf to be larger than an HTTP GET request. This made the web client fail when uip_buf was smaller, and lead to memory corruption. Also, there was a bug when HTTP request headers would arrive when the GET request was being sent out.
This commit is contained in:
parent
6b34b4f092
commit
8526049749
|
@ -29,7 +29,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the "contiki" web browser.
|
* This file is part of the "contiki" web browser.
|
||||||
*
|
*
|
||||||
* $Id: webclient.c,v 1.5 2007/11/30 21:53:50 oliverschmidt Exp $
|
* $Id: webclient.c,v 1.6 2008/11/09 12:39:31 adamdunkels Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -161,40 +161,85 @@ webclient_get(char *host, u16_t port, char *file)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static char * CC_FASTCALL
|
/* Copy data into a "window", specified by the windowstart and
|
||||||
copy_string(char *dest, const char *src, unsigned char len)
|
windowend variables. Only data that fits within the window is
|
||||||
|
copied. This function is used to copy data into the uIP buffer, which
|
||||||
|
typically is smaller than the data that is to be copied.
|
||||||
|
*/
|
||||||
|
static unsigned char *windowptr;
|
||||||
|
static int windowstart, windowend;
|
||||||
|
static int
|
||||||
|
window_copy(int curptr, const char *data, unsigned char datalen)
|
||||||
{
|
{
|
||||||
return strcpy(dest, src) + len;
|
int len;
|
||||||
|
|
||||||
|
if(windowstart == windowend) {
|
||||||
|
return curptr + datalen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(curptr + datalen < windowstart) {
|
||||||
|
/* If all the data is before the window, we do not copy the
|
||||||
|
data. */
|
||||||
|
return curptr + datalen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(curptr > windowend) {
|
||||||
|
/* If all the data is after the window, we do not copy the data. */
|
||||||
|
return curptr + datalen;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = datalen;
|
||||||
|
|
||||||
|
/* Trim off data before the window. */
|
||||||
|
data += windowstart - curptr;
|
||||||
|
len -= windowstart - curptr;
|
||||||
|
|
||||||
|
/* Trim off data after the window. */
|
||||||
|
if(len > windowend - windowstart) {
|
||||||
|
len = windowend - windowstart;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(windowptr + windowstart, data, len);
|
||||||
|
windowstart += len;
|
||||||
|
|
||||||
|
return curptr + datalen;
|
||||||
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
senddata(void)
|
senddata(void)
|
||||||
{
|
{
|
||||||
u16_t len;
|
u16_t len;
|
||||||
char *getrequest;
|
/* char *getrequest;*/
|
||||||
char *cptr;
|
char *cptr;
|
||||||
|
int curptr;
|
||||||
|
|
||||||
if(s.getrequestleft > 0) {
|
if(s.getrequestleft > 0) {
|
||||||
cptr = getrequest = (char *)uip_appdata;
|
|
||||||
|
|
||||||
cptr = copy_string(cptr, http_get, sizeof(http_get) - 1);
|
windowstart = s.getrequestptr;
|
||||||
cptr = copy_string(cptr, s.file, (unsigned char)strlen(s.file));
|
curptr = 0;
|
||||||
*cptr++ = ISO_space;
|
windowend = windowstart + uip_mss();
|
||||||
cptr = copy_string(cptr, http_10, sizeof(http_10) - 1);
|
windowptr = (char *)uip_appdata - windowstart;
|
||||||
|
|
||||||
cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
|
curptr = window_copy(curptr, http_get, sizeof(http_get) - 1);
|
||||||
|
curptr = window_copy(curptr, s.file, (unsigned char)strlen(s.file));
|
||||||
|
curptr = window_copy(curptr, " ", 1);
|
||||||
|
curptr = window_copy(curptr, http_10, sizeof(http_10) - 1);
|
||||||
|
|
||||||
cptr = copy_string(cptr, http_host, sizeof(http_host) - 1);
|
curptr = window_copy(curptr, http_crnl, sizeof(http_crnl) - 1);
|
||||||
cptr = copy_string(cptr, s.host, (unsigned char)strlen(s.host));
|
|
||||||
cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
|
|
||||||
|
|
||||||
cptr = copy_string(cptr, http_user_agent_fields,
|
curptr = window_copy(curptr, http_host, sizeof(http_host) - 1);
|
||||||
|
curptr = window_copy(curptr, s.host, (unsigned char)strlen(s.host));
|
||||||
|
curptr = window_copy(curptr, http_crnl, sizeof(http_crnl) - 1);
|
||||||
|
|
||||||
|
curptr = window_copy(curptr, http_user_agent_fields,
|
||||||
(unsigned char)strlen(http_user_agent_fields));
|
(unsigned char)strlen(http_user_agent_fields));
|
||||||
|
|
||||||
|
|
||||||
len = s.getrequestleft > uip_mss()?
|
len = s.getrequestleft > uip_mss()?
|
||||||
uip_mss():
|
uip_mss():
|
||||||
s.getrequestleft;
|
s.getrequestleft;
|
||||||
uip_send(&(getrequest[s.getrequestptr]), len);
|
uip_send(uip_appdata, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -369,6 +414,8 @@ newdata(void)
|
||||||
void
|
void
|
||||||
webclient_appcall(void *state)
|
webclient_appcall(void *state)
|
||||||
{
|
{
|
||||||
|
char *dataptr;
|
||||||
|
|
||||||
if(uip_connected()) {
|
if(uip_connected()) {
|
||||||
s.timer = 0;
|
s.timer = 0;
|
||||||
s.state = WEBCLIENT_STATE_STATUSLINE;
|
s.state = WEBCLIENT_STATE_STATUSLINE;
|
||||||
|
@ -382,6 +429,10 @@ webclient_appcall(void *state)
|
||||||
webclient_timedout();
|
webclient_timedout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(uip_aborted()) {
|
||||||
|
webclient_aborted();
|
||||||
|
}
|
||||||
|
|
||||||
if(state == NULL) {
|
if(state == NULL) {
|
||||||
uip_abort();
|
uip_abort();
|
||||||
return;
|
return;
|
||||||
|
@ -393,10 +444,11 @@ webclient_appcall(void *state)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uip_aborted()) {
|
|
||||||
webclient_aborted();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
dataptr = uip_appdata;
|
||||||
|
|
||||||
if(uip_acked()) {
|
if(uip_acked()) {
|
||||||
s.timer = 0;
|
s.timer = 0;
|
||||||
|
@ -406,6 +458,9 @@ webclient_appcall(void *state)
|
||||||
s.timer = 0;
|
s.timer = 0;
|
||||||
newdata();
|
newdata();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uip_appdata = dataptr;
|
||||||
|
|
||||||
if(uip_rexmit() ||
|
if(uip_rexmit() ||
|
||||||
uip_newdata() ||
|
uip_newdata() ||
|
||||||
uip_acked()) {
|
uip_acked()) {
|
||||||
|
|
Loading…
Reference in a new issue