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; }