mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
fixed POST issues in axhttpd
git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@126 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
parent
7c7e89b540
commit
1d263c9ab4
3
Makefile
3
Makefile
@ -60,7 +60,8 @@ release:
|
|||||||
$(MAKE) -C config/scripts/config clean
|
$(MAKE) -C config/scripts/config clean
|
||||||
-$(MAKE) clean
|
-$(MAKE) clean
|
||||||
-@rm config/*.msi config/*.back.aip config/config.h config/.config*
|
-@rm config/*.msi config/*.back.aip config/config.h config/.config*
|
||||||
@rm -fr $(STAGE)
|
-@rm www/index.20*
|
||||||
|
-@rm -fr $(STAGE)
|
||||||
@echo "#define AXTLS_VERSION \"$(VERSION)\"" > ssl/version.h
|
@echo "#define AXTLS_VERSION \"$(VERSION)\"" > ssl/version.h
|
||||||
cd ../; tar cvfz $(RELEASE).tar.gz --wildcards-match-slash --exclude .svn axTLS; cd -;
|
cd ../; tar cvfz $(RELEASE).tar.gz --wildcards-match-slash --exclude .svn axTLS; cd -;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#ifdef CONFIG_HTTP_HAS_IPV6
|
#ifdef CONFIG_HTTP_HAS_IPV6
|
||||||
#define HAVE_IPV6
|
#define HAVE_IPV6
|
||||||
#endif
|
#endif
|
||||||
|
#define MAXPOSTDATASIZE 30000
|
||||||
#define MAXREQUESTLENGTH 256
|
#define MAXREQUESTLENGTH 256
|
||||||
#define BLOCKSIZE 4096
|
#define BLOCKSIZE 4096
|
||||||
|
|
||||||
@ -88,6 +88,9 @@ struct connstruct
|
|||||||
#if defined(CONFIG_HTTP_HAS_AUTHORIZATION)
|
#if defined(CONFIG_HTTP_HAS_AUTHORIZATION)
|
||||||
char authorization[MAXREQUESTLENGTH];
|
char authorization[MAXREQUESTLENGTH];
|
||||||
#endif
|
#endif
|
||||||
|
int post_read;
|
||||||
|
int post_state;
|
||||||
|
char *post_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct serverstruct
|
struct serverstruct
|
||||||
@ -125,7 +128,7 @@ void procreadhead(struct connstruct *cn);
|
|||||||
void procsendhead(struct connstruct *cn);
|
void procsendhead(struct connstruct *cn);
|
||||||
void procreadfile(struct connstruct *cn);
|
void procreadfile(struct connstruct *cn);
|
||||||
void procsendfile(struct connstruct *cn);
|
void procsendfile(struct connstruct *cn);
|
||||||
|
void read_post_data(struct connstruct *cn);
|
||||||
|
|
||||||
/* misc.c prototypes */
|
/* misc.c prototypes */
|
||||||
char *my_strncpy(char *dest, const char *src, size_t n);
|
char *my_strncpy(char *dest, const char *src, size_t n);
|
||||||
|
@ -24,6 +24,20 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include "axhttp.h"
|
#include "axhttp.h"
|
||||||
|
|
||||||
|
#if AXDEBUG
|
||||||
|
#define AXDEBUGSTART \
|
||||||
|
{ \
|
||||||
|
FILE *dout; \
|
||||||
|
dout = fopen("/var/log/axdebug", "a"); \
|
||||||
|
|
||||||
|
#define AXDEBUGEND \
|
||||||
|
fclose(dout); \
|
||||||
|
}
|
||||||
|
#else /* AXDEBUG */
|
||||||
|
#define AXDEBUGSTART
|
||||||
|
#define AXDEBUGEND
|
||||||
|
#endif /* AXDEBUG */
|
||||||
|
|
||||||
struct serverstruct *servers;
|
struct serverstruct *servers;
|
||||||
struct connstruct *usedconns;
|
struct connstruct *usedconns;
|
||||||
struct connstruct *freeconns;
|
struct connstruct *freeconns;
|
||||||
@ -161,6 +175,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
addcgiext(CONFIG_HTTP_CGI_EXTENSIONS);
|
addcgiext(CONFIG_HTTP_CGI_EXTENSIONS);
|
||||||
|
printf("addcgiext %s\n",CONFIG_HTTP_CGI_EXTENSIONS);
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_HTTP_VERBOSE)
|
#if defined(CONFIG_HTTP_VERBOSE)
|
||||||
printf("%s: listening on ports %d (http) and %d (https)\n",
|
printf("%s: listening on ports %d (http) and %d (https)\n",
|
||||||
@ -176,6 +191,7 @@ int main(int argc, char *argv[])
|
|||||||
setuid(32767);
|
setuid(32767);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_HTTP_IS_DAEMON
|
#ifdef CONFIG_HTTP_IS_DAEMON
|
||||||
|
fprintf(stderr, "ERR: fork is not working on uclinux\n");
|
||||||
if (fork() > 0) /* parent will die */
|
if (fork() > 0) /* parent will die */
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
@ -283,6 +299,9 @@ int main(int argc, char *argv[])
|
|||||||
FD_ISSET(to->networkdesc, &rfds))
|
FD_ISSET(to->networkdesc, &rfds))
|
||||||
{
|
{
|
||||||
active--;
|
active--;
|
||||||
|
if (to->post_state)
|
||||||
|
read_post_data(to);
|
||||||
|
else
|
||||||
procreadhead(to);
|
procreadhead(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
183
httpd/proc.c
183
httpd/proc.c
@ -54,6 +54,20 @@ static void decode_path_info(struct connstruct *cn, char *path_info);
|
|||||||
static int auth_check(struct connstruct *cn);
|
static int auth_check(struct connstruct *cn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if AXDEBUG
|
||||||
|
#define AXDEBUGSTART \
|
||||||
|
{ \
|
||||||
|
FILE *axdout; \
|
||||||
|
axdout = fopen("/var/log/axdebug", "a"); \
|
||||||
|
|
||||||
|
#define AXDEBUGEND \
|
||||||
|
fclose(axdout); \
|
||||||
|
}
|
||||||
|
#else /* AXDEBUG */
|
||||||
|
#define AXDEBUGSTART
|
||||||
|
#define AXDEBUGEND
|
||||||
|
#endif /* AXDEBUG */
|
||||||
|
|
||||||
/* Returns 1 if elems should continue being read, 0 otherwise */
|
/* Returns 1 if elems should continue being read, 0 otherwise */
|
||||||
static int procheadelem(struct connstruct *cn, char *buf)
|
static int procheadelem(struct connstruct *cn, char *buf)
|
||||||
{
|
{
|
||||||
@ -267,11 +281,113 @@ static void urlencode(const uint8_t *s, char *t)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int init_read_post_data(char *buf, char *data, struct connstruct *cn, int old_rv)
|
||||||
|
{
|
||||||
|
char *next;
|
||||||
|
int rv;
|
||||||
|
char *post_data;
|
||||||
|
|
||||||
|
rv=old_rv;
|
||||||
|
next=data;
|
||||||
|
|
||||||
|
/* Too much Post data to send. MAXPOSTDATASIZE should be
|
||||||
|
configured (now it can be chaged in the header file) */
|
||||||
|
if (cn->content_length > MAXPOSTDATASIZE)
|
||||||
|
{
|
||||||
|
send_error(cn, 418);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove CRLF */
|
||||||
|
while ((*next == '\r' || *next == '\n') && (next < &buf[rv]))
|
||||||
|
next++;
|
||||||
|
|
||||||
|
if (cn->post_data == NULL)
|
||||||
|
{
|
||||||
|
cn->post_data = (char *) calloc(1, (cn->content_length + 1));
|
||||||
|
/* Allocate buffer for the POST data that will be used by proccgi
|
||||||
|
to send POST data to the CGI script */
|
||||||
|
|
||||||
|
if (cn->post_data == NULL)
|
||||||
|
{
|
||||||
|
printf("axhttpd: could not allocate memory for POST data\n");
|
||||||
|
TTY_FLUSH();
|
||||||
|
send_error(cn, 599);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cn->post_state = 0;
|
||||||
|
cn->post_read = 0;
|
||||||
|
post_data = cn->post_data;
|
||||||
|
|
||||||
|
while (next < &buf[rv])
|
||||||
|
{
|
||||||
|
/*copy POST data to buffer*/
|
||||||
|
*post_data = *next;
|
||||||
|
post_data++;
|
||||||
|
next++;
|
||||||
|
cn->post_read++;
|
||||||
|
if (cn->post_read == cn->content_length)
|
||||||
|
{
|
||||||
|
/* No more POST data to be copied */
|
||||||
|
*post_data = '\0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* More POST data has to be read. read_post_data will continue with that */
|
||||||
|
cn->post_state = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_post_data(struct connstruct *cn)
|
||||||
|
{
|
||||||
|
char buf[MAXREQUESTLENGTH*4], *next;
|
||||||
|
char *post_data;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
bzero(buf,MAXREQUESTLENGTH*4);
|
||||||
|
rv = special_read(cn, buf, sizeof(buf)-1);
|
||||||
|
if (rv <= 0)
|
||||||
|
{
|
||||||
|
if (rv < 0) /* really dead? */
|
||||||
|
removeconnection(cn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[rv] = '\0';
|
||||||
|
next = buf;
|
||||||
|
|
||||||
|
post_data = &cn->post_data[cn->post_read];
|
||||||
|
|
||||||
|
while (next < &buf[rv])
|
||||||
|
{
|
||||||
|
*post_data = *next;
|
||||||
|
post_data++;
|
||||||
|
next++;
|
||||||
|
cn->post_read++;
|
||||||
|
if (cn->post_read == cn->content_length)
|
||||||
|
{
|
||||||
|
/* No more POST data to be copied */
|
||||||
|
*post_data='\0';
|
||||||
|
cn->post_state = 0;
|
||||||
|
buildactualfile(cn);
|
||||||
|
cn->state = STATE_WANT_TO_SEND_HEAD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* More POST data to read */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void procreadhead(struct connstruct *cn)
|
void procreadhead(struct connstruct *cn)
|
||||||
{
|
{
|
||||||
char buf[MAXREQUESTLENGTH*4], *tp, *next;
|
char buf[MAXREQUESTLENGTH*4], *tp, *next;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
bzero(buf,MAXREQUESTLENGTH*4);
|
||||||
rv = special_read(cn, buf, sizeof(buf)-1);
|
rv = special_read(cn, buf, sizeof(buf)-1);
|
||||||
if (rv <= 0)
|
if (rv <= 0)
|
||||||
{
|
{
|
||||||
@ -293,6 +409,12 @@ void procreadhead(struct connstruct *cn)
|
|||||||
/* If we have a blank line, advance to next stage */
|
/* If we have a blank line, advance to next stage */
|
||||||
if (*next == '\r' || *next == '\n')
|
if (*next == '\r' || *next == '\n')
|
||||||
{
|
{
|
||||||
|
if ((cn->reqtype == TYPE_POST)&&(cn->content_length > 0))
|
||||||
|
{
|
||||||
|
if (init_read_post_data(buf,next,cn,rv) == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
buildactualfile(cn);
|
buildactualfile(cn);
|
||||||
cn->state = STATE_WANT_TO_SEND_HEAD;
|
cn->state = STATE_WANT_TO_SEND_HEAD;
|
||||||
return;
|
return;
|
||||||
@ -349,6 +471,7 @@ void procsendhead(struct connstruct *cn)
|
|||||||
file_exists = stat(cn->actualfile, &stbuf);
|
file_exists = stat(cn->actualfile, &stbuf);
|
||||||
|
|
||||||
#if defined(CONFIG_HTTP_HAS_CGI)
|
#if defined(CONFIG_HTTP_HAS_CGI)
|
||||||
|
|
||||||
if (file_exists != -1 && cn->is_cgi)
|
if (file_exists != -1 && cn->is_cgi)
|
||||||
{
|
{
|
||||||
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
if ((stbuf.st_mode & S_IEXEC) == 0 || isdir(cn->actualfile))
|
||||||
@ -503,12 +626,13 @@ void procsendfile(struct connstruct *cn)
|
|||||||
|
|
||||||
static void proccgi(struct connstruct *cn)
|
static void proccgi(struct connstruct *cn)
|
||||||
{
|
{
|
||||||
int tpipe[2];
|
int tpipe[2], spipe[2];
|
||||||
char *myargs[2];
|
char *myargs[2];
|
||||||
char cgienv[CGI_ARG_SIZE][MAXREQUESTLENGTH];
|
char cgienv[CGI_ARG_SIZE][MAXREQUESTLENGTH];
|
||||||
char * cgiptr[CGI_ARG_SIZE+4];
|
char * cgiptr[CGI_ARG_SIZE+4];
|
||||||
const char *type = "HEAD";
|
const char *type = "HEAD";
|
||||||
int cgi_index = 0, i;
|
int cgi_index = 0, i;
|
||||||
|
pid_t pid;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
int tmp_stdout;
|
int tmp_stdout;
|
||||||
#endif
|
#endif
|
||||||
@ -531,10 +655,41 @@ static void proccgi(struct connstruct *cn)
|
|||||||
|
|
||||||
/* win32 cgi is a bit too painful */
|
/* win32 cgi is a bit too painful */
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
pipe(tpipe);
|
/* set up pipe that is used for sending POST query data to CGI script*/
|
||||||
|
if (cn->reqtype == TYPE_POST)
|
||||||
if (fork() > 0) /* parent */
|
|
||||||
{
|
{
|
||||||
|
if (pipe(spipe) == -1)
|
||||||
|
{
|
||||||
|
printf("[CGI]: could not create pipe");
|
||||||
|
TTY_FLUSH();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pipe(tpipe) == -1)
|
||||||
|
{
|
||||||
|
printf("[CGI]: could not create pipe");
|
||||||
|
TTY_FLUSH();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef EMBED
|
||||||
|
if ((pid = vfork()) > 0) /* parent */
|
||||||
|
#else
|
||||||
|
if ((pid = fork()) > 0) /* parent */
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* Send POST query data to CGI script */
|
||||||
|
if ((cn->reqtype == TYPE_POST) && (cn->content_length > 0))
|
||||||
|
{
|
||||||
|
write(spipe[1], cn->post_data, cn->content_length);
|
||||||
|
close(spipe[0]);
|
||||||
|
close(spipe[1]);
|
||||||
|
|
||||||
|
/* free the memory that is allocated in read_post_data() */
|
||||||
|
free(cn->post_data);
|
||||||
|
cn->post_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Close the write descriptor */
|
/* Close the write descriptor */
|
||||||
close(tpipe[1]);
|
close(tpipe[1]);
|
||||||
cn->filedesc = tpipe[0];
|
cn->filedesc = tpipe[0];
|
||||||
@ -543,6 +698,9 @@ static void proccgi(struct connstruct *cn)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pid < 0) /* fork failed */
|
||||||
|
exit(1);
|
||||||
|
|
||||||
/* The problem child... */
|
/* The problem child... */
|
||||||
|
|
||||||
/* Our stdout/stderr goes to the socket */
|
/* Our stdout/stderr goes to the socket */
|
||||||
@ -551,13 +709,10 @@ static void proccgi(struct connstruct *cn)
|
|||||||
|
|
||||||
/* If it was a POST request, send the socket data to our stdin */
|
/* If it was a POST request, send the socket data to our stdin */
|
||||||
if (cn->reqtype == TYPE_POST)
|
if (cn->reqtype == TYPE_POST)
|
||||||
dup2(cn->networkdesc, 0);
|
dup2(spipe[0], 0);
|
||||||
else /* Otherwise we can shutdown the read side of the sock */
|
else /* Otherwise we can shutdown the read side of the sock */
|
||||||
shutdown(cn->networkdesc, 0);
|
shutdown(cn->networkdesc, 0);
|
||||||
|
|
||||||
close(tpipe[0]);
|
|
||||||
close(tpipe[1]);
|
|
||||||
|
|
||||||
myargs[0] = cn->actualfile;
|
myargs[0] = cn->actualfile;
|
||||||
myargs[1] = NULL;
|
myargs[1] = NULL;
|
||||||
|
|
||||||
@ -617,7 +772,7 @@ static void proccgi(struct connstruct *cn)
|
|||||||
if (cgi_index >= CGI_ARG_SIZE)
|
if (cgi_index >= CGI_ARG_SIZE)
|
||||||
{
|
{
|
||||||
printf("Content-type: text/plain\n\nToo many CGI args\n");
|
printf("Content-type: text/plain\n\nToo many CGI args\n");
|
||||||
return;
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy across the pointer indexes */
|
/* copy across the pointer indexes */
|
||||||
@ -631,6 +786,7 @@ static void proccgi(struct connstruct *cn)
|
|||||||
|
|
||||||
execve(myargs[0], myargs, cgiptr);
|
execve(myargs[0], myargs, cgiptr);
|
||||||
printf("Content-type: text/plain\n\nshouldn't get here\n");
|
printf("Content-type: text/plain\n\nshouldn't get here\n");
|
||||||
|
exit(1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,10 +971,14 @@ static void buildactualfile(struct connstruct *cn)
|
|||||||
if (cn->is_lua)
|
if (cn->is_lua)
|
||||||
#ifdef CONFIG_PLATFORM_CYGWIN
|
#ifdef CONFIG_PLATFORM_CYGWIN
|
||||||
sprintf(cn->actualfile, "%s/bin/cgi.exe", CONFIG_HTTP_LUA_PREFIX);
|
sprintf(cn->actualfile, "%s/bin/cgi.exe", CONFIG_HTTP_LUA_PREFIX);
|
||||||
|
#else
|
||||||
|
#ifdef EMBED
|
||||||
|
sprintf(cn->actualfile, "%s", CONFIG_HTTP_LUA_PREFIX);
|
||||||
#else
|
#else
|
||||||
sprintf(cn->actualfile, "%s/bin/cgi", CONFIG_HTTP_LUA_PREFIX);
|
sprintf(cn->actualfile, "%s/bin/cgi", CONFIG_HTTP_LUA_PREFIX);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sanitizefile(const char *buf)
|
static int sanitizefile(const char *buf)
|
||||||
@ -1007,6 +1167,11 @@ static void send_error(struct connstruct *cn, int err)
|
|||||||
text = title;
|
text = title;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 418:
|
||||||
|
title = "POST data size is to large";
|
||||||
|
text = title;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
title = "Unknown";
|
title = "Unknown";
|
||||||
text = "Unknown";
|
text = "Unknown";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user