Skip to content
Snippets Groups Projects
Commit 9fe75b49 authored by Doug Bailey's avatar Doug Bailey
Browse files

Add patch to handle how IE7 issues POST requests using Window path spec...

Add patch to handle how IE7 issues POST requests using Window path spec including backslash delimiters


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@151722 65c4cc65-6c06-0410-ace0-fbb531ad65f3
parent 107d4284
No related branches found
No related tags found
No related merge requests found
......@@ -153,17 +153,140 @@ static int process_message(GMimeMessage *message, const char *post_dir)
return cbinfo.count;
}
/* Find a sequence of bytes within a binary array. */
static int find_sequence(char * inbuf, int inlen, char * matchbuf, int matchlen)
{
int current;
int comp;
int found = 0;
for (current = 0; current < inlen-matchlen; current++, inbuf++) {
if (*inbuf == *matchbuf) {
found=1;
for (comp = 1; comp < matchlen; comp++) {
if (inbuf[comp] != matchbuf[comp]) {
found = 0;
break;
}
}
if (found) {
break;
}
}
}
if (found) {
return current;
} else {
return -1;
}
}
/*
* The following is a work around to deal with how IE7 embeds the local file name
* within the Mime header using full WINDOWS file path with backslash directory delimiters.
* This section of code attempts to isolate the directory path and remove it
* from what is written into the output file. In addition, it changes
* esc chars (i.e. backslashes) to forward slashes.
* This function has two modes. The first to find a boundary marker. The
* second is to find the filename immediately after the boundary.
*/
static int readmimefile(FILE * fin, FILE * fout, char * boundary, int contentlen)
{
int find_filename = 0;
char buf[4096];
int marker;
int x;
int char_in_buf = 0;
int num_to_read;
int boundary_len;
char * path_end, * path_start, * filespec;
if (NULL == fin || NULL == fout || NULL == boundary || 0 >= contentlen) {
return -1;
}
boundary_len = strlen(boundary);
while (0 < contentlen || 0 < char_in_buf) {
/* determine how much I will read into the buffer */
if (contentlen > sizeof(buf) - char_in_buf) {
num_to_read = sizeof(buf)- char_in_buf;
} else {
num_to_read = contentlen;
}
if(0 < num_to_read) {
fread(&(buf[char_in_buf]), 1, num_to_read, fin);
contentlen -= num_to_read;
char_in_buf += num_to_read;
}
/* If I am looking for the filename spec */
if (find_filename) {
path_end = filespec = NULL;
x = strlen("filename=\"");
marker = find_sequence(buf, char_in_buf, "filename=\"", x );
if (0 <= marker) {
marker += x; /* Index beyond the filename marker */
path_start = &buf[marker];
for (path_end = path_start, x = 0; x < char_in_buf-marker; x++, path_end++) {
if ('\\' == *path_end) { /* convert backslashses to forward slashes */
*path_end = '/';
}
if ('\"' == *path_end) { /* If at the end of the file name spec */
*path_end = '\0'; /* temporarily null terminate the file spec for basename */
filespec = basename(path_start);
*path_end = '\"';
break;
}
}
}
if (filespec) { /* If the file name path was found in the header */
fwrite(buf, 1, marker, fout);
x = (int)(path_end+1 - filespec);
fwrite(filespec, 1, x, fout);
x = (int)(path_end+1 - buf);
memmove(buf, &(buf[x]), char_in_buf-x);
char_in_buf -= x;
}
find_filename = 0;
} else { /* I am looking for the boundary marker */
marker = find_sequence(buf, char_in_buf, boundary, boundary_len);
if (0 > marker) {
if (char_in_buf < (boundary_len)) {
/*no possibility to find the boundary, write all you have */
fwrite(buf, 1, char_in_buf, fout);
char_in_buf = 0;
} else {
/* write all except for area where the boundary marker could be */
fwrite(buf, 1, char_in_buf -(boundary_len -1), fout);
x = char_in_buf -(boundary_len -1);
memmove(buf, &(buf[x]), char_in_buf-x);
char_in_buf = (boundary_len -1);
}
} else {
/* write up through the boundary, then look for filename in the rest */
fwrite(buf, 1, marker + boundary_len, fout);
x = marker + boundary_len;
memmove(buf, &(buf[x]), char_in_buf-x);
char_in_buf -= marker + boundary_len;
find_filename =1;
}
}
}
return 0;
}
static struct ast_str *http_post_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *vars, struct ast_variable *headers, int *status, char **title, int *contentlength)
{
struct ast_variable *var;
unsigned long ident = 0;
char buf[4096];
FILE *f;
size_t res;
int content_len = 0;
struct ast_str *post_dir;
GMimeMessage *message;
int message_count = 0;
char * boundary_marker = NULL;
if (!urih) {
return ast_http_error((*status = 400),
......@@ -213,17 +336,23 @@ static struct ast_str *http_post_callback(struct ast_tcptls_session_instance *se
return NULL;
}
ast_debug(1, "Got a Content-Length of %d\n", content_len);
} else if (!strcasecmp(var->name, "Content-Type")) {
boundary_marker = strstr(var->value, "boundary=");
if (boundary_marker) {
boundary_marker += strlen("boundary=");
}
}
}
fprintf(f, "\r\n");
for (res = sizeof(buf); content_len; content_len -= res) {
if (content_len < res) {
res = content_len;
if (0 > readmimefile(ser->f, f, boundary_marker, content_len)) {
if (option_debug) {
ast_log(LOG_DEBUG, "Cannot find boundary marker in POST request.\n");
}
fread(buf, 1, res, ser->f);
fwrite(buf, 1, res, f);
fclose(f);
return NULL;
}
if (fseek(f, SEEK_SET, 0)) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment