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
1.6.2
Doug Bailey 17 years ago
parent 107d4284ae
commit 9fe75b494a

@ -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)) {

Loading…
Cancel
Save