<commit_before>(*
 * Copyright (C) 2006-2009 Citrix Systems Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 only. with the special
 * exception on linking described in file LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *)
(** HTTP handler for importing a raw VDI.
 * @group Import and Export
 *)

module D=Debug.Debugger(struct let name="import" end)
open D

open Http
open Importexport
open Sparse_encoding
open Unixext
open Pervasiveext
open Client

let receive_chunks (s: Unix.file_descr) (fd: Unix.file_descr) = 
	Chunk.fold (fun () -> Chunk.write fd) () s

let vdi_of_req ~__context (req: request) = 
	let all = req.Http.query @ req.Http.cookie in
	let vdi = 
		if List.mem_assoc "vdi" all
		then List.assoc "vdi" all
		else raise (Failure "Missing vdi query parameter") in
	if Db.is_valid_ref __context (Ref.of_string vdi) 
	then Ref.of_string vdi 
	else Db.VDI.get_by_uuid ~__context ~uuid:vdi

let localhost_handler rpc session_id (req: request) (s: Unix.file_descr) =
  req.close <- true;
  Xapi_http.with_context "Importing raw VDI" req s
    (fun __context ->
	let all = req.Http.query @ req.Http.cookie in
      let vdi = vdi_of_req ~__context req in
      let chunked = List.mem_assoc "chunked" all in
      let task_id = Context.get_task_id __context in
	 debug "import_raw_vdi task_id = %s vdi = %s; chunked = %b" (Ref.string_of task_id) (Ref.string_of vdi) chunked;
	 try
	match req.transfer_encoding with
	| Some x ->
	    error "Chunked encoding not yet implemented in the import code";
	    Http_svr.headers s http_403_forbidden;
	    raise (Failure (Printf.sprintf "import code cannot handle encoding: %s" x))
	| None ->
	    let headers = Http.http_200_ok ~keep_alive:false () @
	      [ Http.task_id_hdr ^ ":" ^ (Ref.string_of task_id);
		content_type ] in
            Http_svr.headers s headers;
	    
		Server_helpers.exec_with_new_task "VDI.import" 
		(fun __context -> 
		 Sm_fs_ops.with_open_block_attached_device __context rpc session_id vdi `RW
		   (fun fd ->
			   try
			     if chunked
			     then receive_chunks s fd
			     else ignore(Unixext.copy_file ?limit:req.content_length s fd);
			     Unixext.fsync fd;
			   with Unix.Unix_error(Unix.EIO, _, _) ->
			     raise (Api_errors.Server_error (Api_errors.vdi_io_error, ["Device I/O errors"]))
		   )
	    );
	    TaskHelper.complete ~__context [];
      with e ->
	error "Caught exception: %s" (ExnHelper.string_of_exn e);
	log_backtrace ();
	TaskHelper.failed ~__context (Api_errors.internal_error, ["Caught exception: " ^ (ExnHelper.string_of_exn e)]);
	raise e)

let return_302_redirect (req: request) s address =<commit_msg>CA-48594: slightly improve the error handling of HTTP raw VDI upload<commit_after>(*
 * Copyright (C) 2006-2009 Citrix Systems Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 only. with the special
 * exception on linking described in file LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *)
(** HTTP handler for importing a raw VDI.
 * @group Import and Export
 *)

module D=Debug.Debugger(struct let name="import" end)
open D

open Http
open Importexport
open Sparse_encoding
open Unixext
open Pervasiveext
open Client

let receive_chunks (s: Unix.file_descr) (fd: Unix.file_descr) = 
	Chunk.fold (fun () -> Chunk.write fd) () s

let vdi_of_req ~__context (req: request) = 
	let all = req.Http.query @ req.Http.cookie in
	let vdi = 
		if List.mem_assoc "vdi" all
		then List.assoc "vdi" all
		else raise (Failure "Missing vdi query parameter") in
	if Db.is_valid_ref __context (Ref.of_string vdi) 
	then Ref.of_string vdi 
	else Db.VDI.get_by_uuid ~__context ~uuid:vdi

let localhost_handler rpc session_id (req: request) (s: Unix.file_descr) =
  req.close <- true;
  Xapi_http.with_context "Importing raw VDI" req s
    (fun __context ->
	let all = req.Http.query @ req.Http.cookie in
      let vdi = vdi_of_req ~__context req in
      let chunked = List.mem_assoc "chunked" all in
      let task_id = Context.get_task_id __context in
	 debug "import_raw_vdi task_id = %s vdi = %s; chunked = %b" (Ref.string_of task_id) (Ref.string_of vdi) chunked;
	 try
	match req.transfer_encoding with
	| Some x ->
	    error "Chunked encoding not yet implemented in the import code";
	    Http_svr.headers s http_403_forbidden;
	    raise (Failure (Printf.sprintf "import code cannot handle encoding: %s" x))
	| None ->
		Server_helpers.exec_with_new_task "VDI.import" 
		(fun __context -> 
		 Sm_fs_ops.with_open_block_attached_device __context rpc session_id vdi `RW
		   (fun fd ->
			   let headers = Http.http_200_ok ~keep_alive:false () @
				   [ Http.task_id_hdr ^ ":" ^ (Ref.string_of task_id);
				   content_type ] in
               Http_svr.headers s headers;
			   try
			     if chunked
			     then receive_chunks s fd
			     else ignore(Unixext.copy_file ?limit:req.content_length s fd);
			     Unixext.fsync fd;
			   with Unix.Unix_error(Unix.EIO, _, _) ->
			     raise (Api_errors.Server_error (Api_errors.vdi_io_error, ["Device I/O errors"]))
		   )
	    );
	    TaskHelper.complete ~__context [];
      with e ->
	error "Caught exception: %s" (ExnHelper.string_of_exn e);
	log_backtrace ();
	TaskHelper.failed ~__context (Api_errors.internal_error, ["Caught exception: " ^ (ExnHelper.string_of_exn e)]);
	raise e)

let return_302_redirect (req: request) s address =
{'fraction_non_alphanumeric': 0.08994708994708994, 'fraction_numerical': 0.007109788359788359, 'mean_word_length': 3.5310861423220974, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1755109', 'n_tokens_mistral': 2130, 'n_tokens_neox': 1975, 'n_words': 660}