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; FILE *f; 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), (*title = ast_strdup("Missing URI handle")), NULL, "There was an error parsing the request"); } for (var = vars; var; var = var->next) { if (strcasecmp(var->name, "mansession_id")) { continue; } if (sscanf(var->value, "%30lx", &ident) != 1) { return ast_http_error((*status = 400), (*title = ast_strdup("Bad Request")), NULL, "The was an error parsing the request."); } if (!astman_verify_session_writepermissions(ident, EVENT_FLAG_CONFIG)) { return ast_http_error((*status = 401), (*title = ast_strdup("Unauthorized")), NULL, "You are not authorized to make this request."); } break; } if (!var) { return ast_http_error((*status = 401), (*title = ast_strdup("Unauthorized")), NULL, "You are not authorized to make this request."); } if (!(f = tmpfile())) { ast_log(LOG_ERROR, "Could not create temp file.\n"); return NULL; } for (var = headers; var; var = var->next) { fprintf(f, "%s: %s\r\n", var->name, var->value); if (!strcasecmp(var->name, "Content-Length")) { if ((sscanf(var->value, "%30u", &content_len)) != 1) { ast_log(LOG_ERROR, "Invalid Content-Length in POST request!\n"); fclose(f); 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"); 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"); } fclose(f); return NULL; } if (fseek(f, SEEK_SET, 0)) { ast_log(LOG_ERROR, "Failed to seek temp file back to beginning.\n"); fclose(f); return NULL; } post_dir = urih->data; message = parse_message(f); /* Takes ownership and will close f */ if (!message) { ast_log(LOG_ERROR, "Error parsing MIME data\n"); return ast_http_error((*status = 400), (*title = ast_strdup("Bad Request")), NULL, "The was an error parsing the request."); } if (!(message_count = process_message(message, ast_str_buffer(post_dir)))) { ast_log(LOG_ERROR, "Invalid MIME data, found no parts!\n"); g_object_unref(message); return ast_http_error((*status = 400), (*title = ast_strdup("Bad Request")), NULL, "The was an error parsing the request."); } g_object_unref(message); return ast_http_error((*status = 200), (*title = ast_strdup("OK")), NULL, "File successfully uploaded."); }
static int 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 *get_vars, struct ast_variable *headers) { struct ast_variable *var; uint32_t ident; FILE *f; int content_len = 0; struct ast_str *post_dir; GMimeMessage *message; char *boundary_marker = NULL; if (method != AST_HTTP_POST) { ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method"); return 0; } if (!urih) { ast_http_error(ser, 400, "Missing URI handle", "There was an error parsing the request"); return 0; } ident = ast_http_manid_from_vars(headers); if (!ident || !astman_is_authed(ident)) { ast_http_request_close_on_completion(ser); ast_http_error(ser, 403, "Access Denied", "Sorry, I cannot let you do that, Dave."); return 0; } if (!astman_verify_session_writepermissions(ident, EVENT_FLAG_CONFIG)) { ast_http_request_close_on_completion(ser); ast_http_error(ser, 401, "Unauthorized", "You are not authorized to make this request."); return 0; } if (!(f = tmpfile())) { ast_log(LOG_ERROR, "Could not create temp file.\n"); ast_http_error(ser, 500, "Internal server error", "Could not create temp file."); return 0; } for (var = headers; var; var = var->next) { fprintf(f, "%s: %s\r\n", var->name, var->value); if (!strcasecmp(var->name, "Content-Length")) { if ((sscanf(var->value, "%30u", &content_len)) != 1) { ast_log(LOG_ERROR, "Invalid Content-Length in POST request!\n"); fclose(f); ast_http_request_close_on_completion(ser); ast_http_error(ser, 400, "Bad Request", "Invalid Content-Length in POST request!"); return 0; } 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"); /* * Always mark the body read as failed. * * XXX Should change readmimefile() to always be sure to read * the entire body so we can update the read status and * potentially keep the connection open. */ ast_http_body_read_status(ser, 0); if (0 > readmimefile(ser->stream, f, boundary_marker, content_len)) { ast_debug(1, "Cannot find boundary marker in POST request.\n"); fclose(f); ast_http_error(ser, 400, "Bad Request", "Cannot find boundary marker in POST request."); return 0; } if (fseek(f, SEEK_SET, 0)) { ast_log(LOG_ERROR, "Failed to seek temp file back to beginning.\n"); fclose(f); ast_http_error(ser, 500, "Internal server error", "Failed to seek temp file back to beginning."); return 0; } post_dir = urih->data; message = parse_message(f); /* Takes ownership and will close f */ if (!message) { ast_log(LOG_ERROR, "Error parsing MIME data\n"); ast_http_error(ser, 400, "Bad Request", "There was an error parsing the request."); return 0; } if (!process_message(message, ast_str_buffer(post_dir))) { ast_log(LOG_ERROR, "Invalid MIME data, found no parts!\n"); g_object_unref(message); ast_http_error(ser, 400, "Bad Request", "There was an error parsing the request."); return 0; } g_object_unref(message); /* XXX Passing 200 to the error response routine? */ ast_http_error(ser, 200, "OK", "File successfully uploaded."); return 0; }
static int 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 *get_vars, struct ast_variable *headers) { struct ast_variable *var, *cookies; unsigned long ident = 0; FILE *f; int content_len = 0; struct ast_str *post_dir; GMimeMessage *message; int message_count = 0; char * boundary_marker = NULL; if (method != AST_HTTP_POST) { ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method"); return -1; } if (!astman_is_authed(ast_http_manid_from_vars(headers))) { ast_http_error(ser, 403, "Access Denied", "Sorry, I cannot let you do that, Dave."); return -1; } if (!urih) { ast_http_error(ser, 400, "Missing URI handle", "There was an error parsing the request"); return -1; } cookies = ast_http_get_cookies(headers); for (var = cookies; var; var = var->next) { if (!strcasecmp(var->name, "mansession_id")) { sscanf(var->value, "%30lx", &ident); break; } } if (cookies) { ast_variables_destroy(cookies); } if (ident == 0) { ast_http_error(ser, 401, "Unauthorized", "You are not authorized to make this request."); return -1; } if (!astman_verify_session_writepermissions(ident, EVENT_FLAG_CONFIG)) { ast_http_error(ser, 401, "Unauthorized", "You are not authorized to make this request."); return -1; } if (!(f = tmpfile())) { ast_log(LOG_ERROR, "Could not create temp file.\n"); ast_http_error(ser, 500, "Internal server error", "Could not create temp file."); return -1; } for (var = headers; var; var = var->next) { fprintf(f, "%s: %s\r\n", var->name, var->value); if (!strcasecmp(var->name, "Content-Length")) { if ((sscanf(var->value, "%30u", &content_len)) != 1) { ast_log(LOG_ERROR, "Invalid Content-Length in POST request!\n"); fclose(f); ast_http_error(ser, 500, "Internal server error", "Invalid Content-Length in POST request!"); return -1; } 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"); 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"); } fclose(f); return -1; } if (fseek(f, SEEK_SET, 0)) { ast_log(LOG_ERROR, "Failed to seek temp file back to beginning.\n"); fclose(f); ast_http_error(ser, 500, "Internal server error", "Failed to seek temp file back to beginning."); return -1; } post_dir = urih->data; message = parse_message(f); /* Takes ownership and will close f */ if (!message) { ast_log(LOG_ERROR, "Error parsing MIME data\n"); ast_http_error(ser, 400, "Bad Request", "The was an error parsing the request."); return -1; } if (!(message_count = process_message(message, ast_str_buffer(post_dir)))) { ast_log(LOG_ERROR, "Invalid MIME data, found no parts!\n"); g_object_unref(message); ast_http_error(ser, 400, "Bad Request", "The was an error parsing the request."); return -1; } g_object_unref(message); ast_http_error(ser, 200, "OK", "File successfully uploaded."); return 0; }