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.
|
||||
*
|
||||
* $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;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static char * CC_FASTCALL
|
||||
copy_string(char *dest, const char *src, unsigned char len)
|
||||
/* Copy data into a "window", specified by the windowstart and
|
||||
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
|
||||
senddata(void)
|
||||
{
|
||||
u16_t len;
|
||||
char *getrequest;
|
||||
/* char *getrequest;*/
|
||||
char *cptr;
|
||||
int curptr;
|
||||
|
||||
if(s.getrequestleft > 0) {
|
||||
cptr = getrequest = (char *)uip_appdata;
|
||||
|
||||
cptr = copy_string(cptr, http_get, sizeof(http_get) - 1);
|
||||
cptr = copy_string(cptr, s.file, (unsigned char)strlen(s.file));
|
||||
*cptr++ = ISO_space;
|
||||
cptr = copy_string(cptr, http_10, sizeof(http_10) - 1);
|
||||
windowstart = s.getrequestptr;
|
||||
curptr = 0;
|
||||
windowend = windowstart + uip_mss();
|
||||
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);
|
||||
cptr = copy_string(cptr, s.host, (unsigned char)strlen(s.host));
|
||||
cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
|
||||
curptr = window_copy(curptr, 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));
|
||||
|
||||
|
||||
len = s.getrequestleft > uip_mss()?
|
||||
uip_mss():
|
||||
s.getrequestleft;
|
||||
uip_send(&(getrequest[s.getrequestptr]), len);
|
||||
uip_send(uip_appdata, len);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@ -369,6 +414,8 @@ newdata(void)
|
||||
void
|
||||
webclient_appcall(void *state)
|
||||
{
|
||||
char *dataptr;
|
||||
|
||||
if(uip_connected()) {
|
||||
s.timer = 0;
|
||||
s.state = WEBCLIENT_STATE_STATUSLINE;
|
||||
@ -382,6 +429,10 @@ webclient_appcall(void *state)
|
||||
webclient_timedout();
|
||||
}
|
||||
|
||||
if(uip_aborted()) {
|
||||
webclient_aborted();
|
||||
}
|
||||
|
||||
if(state == NULL) {
|
||||
uip_abort();
|
||||
return;
|
||||
@ -393,10 +444,11 @@ webclient_appcall(void *state)
|
||||
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()) {
|
||||
s.timer = 0;
|
||||
@ -406,6 +458,9 @@ webclient_appcall(void *state)
|
||||
s.timer = 0;
|
||||
newdata();
|
||||
}
|
||||
|
||||
uip_appdata = dataptr;
|
||||
|
||||
if(uip_rexmit() ||
|
||||
uip_newdata() ||
|
||||
uip_acked()) {
|
||||
|
Loading…
Reference in New Issue
Block a user