mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47: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