mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
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
This commit is contained in:
@@ -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)) {
|
||||
|
Reference in New Issue
Block a user