first commit

This commit is contained in:
rodrigo committed 2025-04-10 23:07:21 -03:00
commit c9fb67e751
423 files changed
+53287

No files matched your search

+144
View File
@@ -0,0 +1,144 @@
<?php
// Verificar se o usuário está logado
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit();
}
$processed_dir = './processed/';
date_default_timezone_set('America/Araguaina');
if (is_dir($processed_dir)) {
$files = scandir($processed_dir);
$files = array_diff($files, array('.', '..'));
usort($files, function($a, $b) use ($processed_dir) {
return filemtime($processed_dir . $b) - filemtime($processed_dir . $a);
});
} else {
$files = [];
}
// Paginação
$files_per_page = 10;
$total_files = count($files);
$total_pages = ceil($total_files / $files_per_page);
$current_page = isset($_GET['page_num']) ? (int)$_GET['page_num'] : 1;
$current_page = max(1, min($total_pages, $current_page));
$start_index = ($current_page - 1) * $files_per_page;
$paginated_files = array_slice($files, $start_index, $files_per_page);
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Lista de Arquivos Processados</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/css/lightbox.min.css" rel="stylesheet" />
<style>
table { width: 100%; border-collapse: collapse; }
th, td { padding: 10px; text-align: left; border-bottom: 1px solid #ddd; }
th { background-color: #f4f4f4; }
a.download-link { color: #007BFF; text-decoration: none; }
a.download-link:hover { text-decoration: underline; }
.pagination { margin-top: 20px; text-align: center; }
.pagination a { margin: 0 5px; text-decoration: none; color: #007BFF; }
.pagination a:hover { text-decoration: underline; }
.lightbox-container {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
justify-content: center;
align-items: center;
z-index: 1000;
}
.lightbox-content {
width: 80%;
height: 80%;
background-color: #fff;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.lightbox-content iframe {
width: 100%;
height: 100%;
}
.lightbox-close {
position: absolute;
top: 10px;
right: 10px;
background-color: #333;
color: #fff;
border: none;
padding: 5px 10px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h2>Lista de Arquivos Processados</h2>
<table>
<thead>
<tr>
<th>Nome do Arquivo</th>
<th>Data de Modificação</th>
</tr>
</thead>
<tbody>
<?php foreach ($paginated_files as $file): ?>
<tr>
<td>
<a class="download-link" href="#" data-file="<?php echo 'processed/' . urlencode($file); ?>" data-title="<?php echo htmlspecialchars($file); ?>">
<?php echo htmlspecialchars($file); ?>
</a>
</td>
<td><?php echo date("d/m/Y H:i:s", filemtime($processed_dir . $file)); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div class="pagination">
<?php if ($current_page > 1): ?>
<a href="index.php?page=list_files&page_num=<?php echo $current_page - 1; ?>">&laquo; Anterior</a>
<?php endif; ?>
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
<a href="index.php?page=list_files&page_num=<?php echo $i; ?>" <?php if ($i == $current_page) echo 'style="font-weight: bold;"'; ?>><?php echo $i; ?></a>
<?php endfor; ?>
<?php if ($current_page < $total_pages): ?>
<a href="index.php?page=list_files&page_num=<?php echo $current_page + 1; ?>">Próximo &raquo;</a>
<?php endif; ?>
</div>
</div>
<div id="lightbox" class="lightbox-container">
<div class="lightbox-content">
<button class="lightbox-close" onclick="closeLightbox()">Fechar</button>
<iframe id="lightbox-iframe" src="" frameborder="0"></iframe>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('.download-link').on('click', function(e) {
e.preventDefault();
var fileUrl = $(this).data('file');
$('#lightbox-iframe').attr('src', fileUrl);
$('#lightbox').css('display', 'flex'); // Usar flex para centralizar
});
});
function closeLightbox() {
$('#lightbox').hide();
$('#lightbox-iframe').attr('src', '');
}
</script>
</body>
</html>
+508
View File
@@ -0,0 +1,508 @@
<?php
// process_queue.php
ini_set('memory_limit', '512M');
date_default_timezone_set('America/Araguaina');
// Aumentar o tempo máximo de execução do script para 300 segundos (5 minutos)
set_time_limit(300);
// Verifique se a extensão `pcntl` está disponível
if (!function_exists('pcntl_fork')) {
die("A extensão pcntl não está disponível. Por favor, habilite-a para continuar.\n");
}
// Definir o número máximo de processos filhos
define('MAX_CHILDREN', 3);
$childProcesses = [];
// Função para registrar logs
function log_message($message, $level = 'INFO') {
$timestamp = date("Y-m-d H:i:s P"); // Inclui o fuso horário
// Apenas logar mensagens de nível INFO, ERROR e WARN
if (in_array($level, ['INFO', 'ERROR', 'WARN'])) {
file_put_contents('/var/log/process_queue.log', "[$timestamp] [$level] $message\n", FILE_APPEND);
}
}
log_message("Script iniciado.", 'INFO');
function process_file($row) {
// Cada processo filho deve estabelecer sua própria conexão com o banco de dados
$mysqli = new mysqli("10.15.0.42", "root", "34641747", "valida");
if ($mysqli->connect_error) {
log_message("Connection failed: " . $mysqli->connect_error, 'ERROR');
exit(1); // Sair com erro
}
// Assegurar que as mensagens de log incluam o ID do processo
$process_id = getmypid();
log_message("Processo $process_id: Processando arquivo ID " . $row['id'] . ": " . $row['file_path'], 'INFO');
try {
$file_path = $row['file_path'];
$queue_id = $row['id'];
$user_agent = $row['user_agent'];
$ip_address = $row['ip_address'];
$host_name = $row['host_name'];
$access_time = $row['access_time'] . ' ' . date("P"); // Adiciona fuso horário
$language = $row['language'];
$referer = $row['referer'];
$protocol = $row['protocol'];
$connection = $row['connection'];
$viewport_width = $row['viewport_width'];
$viewport_height = $row['viewport_height'];
$original_location = $row['original_location']; // Novo campo para localização original
// Recuperar a porta do cliente
$result_port = $mysqli->query("SELECT port FROM client_ports WHERE queue_id = $queue_id");
$client_port = $result_port->fetch_assoc()['port'] ?? 'N/A';
$result_port->free();
// Atualizar status para 'processing'
$stmt_update = $mysqli->prepare("UPDATE queue SET status = 'processing' WHERE id = ?");
$stmt_update->bind_param("i", $queue_id);
$stmt_update->execute();
$stmt_update->close();
log_message("Processo $process_id: Atualizou status para 'processing' para o arquivo ID $queue_id.", 'INFO');
// Gerar checksums
$checksums = generate_checksums($file_path);
// Capturar data e hora
$file_datetime = get_file_datetime($file_path);
// Registrar timestamp usando OpenTimestamps
$timestamp_result = register_timestamp_opentimestamps($file_path);
$signature_time = date("d/m/Y H:i:s P"); // Inclui fuso horário
if ($timestamp_result['success']) {
$ots_base64 = $timestamp_result['ots_base64'];
// Coletar dados do dispositivo
$device_data = [
'User Agent' => $user_agent,
'IP Address' => $ip_address . ':' . $client_port,
'Host Name' => $host_name,
'Access Time' => $access_time,
'Language' => $language,
'Referer' => $referer,
'Protocol' => $protocol,
'Connection' => $connection,
'Viewport Width' => $viewport_width,
'Viewport Height' => $viewport_height,
'Original Location' => $original_location // Adicionado
];
// Gerar PDF
$pdf_path = generate_pdf($file_path, [
'name' => basename($file_path),
'creation_time' => $file_datetime['creation_time'] . ' ' . date("P", filectime($file_path)),
'modification_time' => $file_datetime['modification_time'] . ' ' . date("P", filemtime($file_path)),
'upload_time' => $access_time,
'signature_time' => $signature_time
], $checksums, $device_data, $ots_base64);
// Atualizar status para 'completed'
$stmt_complete = $mysqli->prepare("UPDATE queue SET status = 'completed' WHERE id = ?");
$stmt_complete->bind_param("i", $queue_id);
$stmt_complete->execute();
$stmt_complete->close();
log_message("Processo $process_id: Processamento concluído para arquivo ID $queue_id: $file_path", 'INFO');
} else {
// Atualizar status para 'error'
$stmt_error = $mysqli->prepare("UPDATE queue SET status = 'error' WHERE id = ?");
$stmt_error->bind_param("i", $queue_id);
$stmt_error->execute();
$stmt_error->close();
log_message("Processo $process_id: Erro ao processar arquivo ID $queue_id: " . $timestamp_result['message'], 'ERROR');
}
} catch (Exception $e) {
// Atualizar status para 'error'
$stmt_exception = $mysqli->prepare("UPDATE queue SET status = 'error' WHERE id = ?");
$stmt_exception->bind_param("i", $queue_id);
$stmt_exception->execute();
$stmt_exception->close();
log_message("Processo $process_id: Exceção ao processar arquivo ID $queue_id: " . $e->getMessage(), 'ERROR');
}
$mysqli->close();
log_message("Processo $process_id: Fechou conexão com o banco de dados para o arquivo ID $queue_id.", 'INFO');
}
// Funções auxiliares (generate_checksums, get_file_datetime, register_timestamp_opentimestamps, generate_pdf)
// Mantenha estas funções como estão no seu código original, sem alterações. Certifique-se de que as funções não dependam de conexões globais de banco de dados.
require_once __DIR__ . '../../vendor/autoload.php';
// Função para gerar checksums
function generate_checksums($file_path) {
log_message("Gerando checksums para $file_path", 'INFO');
$start_time = microtime(true);
// Carregar o conteúdo do arquivo uma única vez
$file_content = file_get_contents($file_path);
$checksums = [
'sha256' => hash('sha256', $file_content),
'sha512' => hash('sha512', $file_content),
'md5' => hash('md5', $file_content)
];
$end_time = microtime(true);
log_message("Checksums gerados em " . round($end_time - $start_time, 4) . " segundos", 'INFO');
return $checksums;
}
// Função para capturar data e hora do arquivo
function get_file_datetime($file_path) {
log_message("Obtendo data e hora do arquivo para $file_path", 'INFO');
$start_time = microtime(true);
$creation_time = date("d/m/Y H:i:s P", filectime($file_path));
$modification_time = date("d/m/Y H:i:s P", filemtime($file_path));
$end_time = microtime(true);
log_message("Data e hora obtidas em " . round($end_time - $start_time, 4) . " segundos", 'INFO');
return [
'creation_time' => $creation_time,
'modification_time' => $modification_time
];
}
// Função para registrar timestamp usando OpenTimestamps
function register_timestamp_opentimestamps($file_path) {
log_message("Registrando timestamp para $file_path", 'INFO');
$start_time = microtime(true);
// Definir diretório de cache para OTS
$ots_cache_dir = '/var/www/html/ots_cache';
if (!is_dir($ots_cache_dir)) {
log_message("Diretório de cache OTS não existe. Criando em $ots_cache_dir", 'INFO');
if (!mkdir($ots_cache_dir, 0755, true)) {
log_message("Erro ao criar diretório de cache OTS: $ots_cache_dir", 'ERROR');
return ['success' => false, 'message' => "Erro ao criar diretório de cache OTS: $ots_cache_dir"];
}
chmod($ots_cache_dir, 0755); // Ajustar permissões
}
// Definir a variável de ambiente antes de executar o comando
$command_stamp = "OTS_CACHE_DIRECTORY=" . escapeshellarg($ots_cache_dir) . " ots stamp " . escapeshellarg($file_path) . " 2>&1";
log_message("Comando para executar: $command_stamp", 'INFO');
// Executar o comando
exec($command_stamp, $output_stamp, $return_var_stamp);
// Verificar o resultado da execução
if ($return_var_stamp !== 0) {
log_message("Erro ao registrar timestamp: " . implode("\n", $output_stamp), 'ERROR');
return ['success' => false, 'message' => 'Erro ao registrar timestamp: ' . implode("\n", $output_stamp)];
}
// Definir o caminho do arquivo .ots gerado
$ots_file = "{$file_path}.ots";
// Verificar se o arquivo .ots foi criado
if (!file_exists($ots_file)) {
log_message("Arquivo de timestamp não encontrado: $ots_file", 'ERROR');
return ['success' => false, 'message' => "Arquivo de timestamp não encontrado: $ots_file"];
}
// Codificar o arquivo .ots em base64
$ots_base64 = base64_encode(file_get_contents($ots_file));
$end_time = microtime(true);
log_message("Timestamp registrado e codificado em " . round($end_time - $start_time, 4) . " segundos", 'INFO');
return ['success' => true, 'ots_base64' => $ots_base64];
}
// Função para gerar PDF
function generate_pdf($uploaded_file_path, $document_info, $checksums, $device_data, $ots_base64) {
log_message("Gerando PDF para $uploaded_file_path", 'INFO');
$start_time = microtime(true);
// Criar uma nova instância do TCPDF
$pdf = new TCPDF();
// Configurações iniciais do PDF
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Seu Nome ou Empresa');
$pdf->SetTitle('Prova de Autenticidade de Documento');
$pdf->SetSubject('Timestamping e Checksums');
// Remover as margens padrão
$pdf->SetMargins(10, 10, 10);
$pdf->SetHeaderMargin(0);
$pdf->SetFooterMargin(0);
// Desativar cabeçalhos e rodapés automáticos
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
// Configurar a fonte padrão uma vez
$pdf->SetFont('helvetica', '', 10);
// Verificar o tipo de arquivo para incorporar no PDF
$file_info = pathinfo($uploaded_file_path);
$extension = strtolower($file_info['extension']);
// Configurar o diretório temporário para o ImageMagick
$temp_dir = '/tmp/imagick';
if (!is_dir($temp_dir)) {
mkdir($temp_dir, 0777, true);
}
chmod($temp_dir, 0777); // Garantir permissões totais
// Configurar o diretório temporário para as imagens
$tmp_dir = '/tmp/image';
if (!is_dir($tmp_dir)) {
mkdir($tmp_dir, 0777, true);
}
chmod($tmp_dir, 0777); // Garantir permissões totais
// Criar uma única instância de Imagick
$imagick = new Imagick();
// Configurar o ambiente para otimização
putenv('MAGICK_TMPDIR=' . $temp_dir); // Defina um diretório temporário adequado
$imagick->setResourceLimit(Imagick::RESOURCETYPE_MEMORY, 512); // Ajuste conforme necessário
$imagick->setResourceLimit(Imagick::RESOURCETYPE_MAP, 512);
$imagick->setResourceLimit(Imagick::RESOURCETYPE_THREAD, 2);
try {
if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif'])) {
log_message("Processando imagem $uploaded_file_path", 'INFO');
// Reduzir a resolução para 1200x900, mantendo a proporção
log_message("Reduzindo resolução da imagem para melhor qualidade e menor tamanho", 'INFO');
$imagick->readImage($uploaded_file_path);
$imagick->resizeImage(1200, 900, Imagick::FILTER_LANCZOS, 1, true);
// Configurar a compressão usando PNG para melhor qualidade sem perder transparência
if ($extension === 'png') {
$imagick->setImageFormat('png');
$imagick->stripImage(); // Remove metadados
$image_blob = $imagick->getImageBlob();
} else {
// Para JPEG e outros, usar alta qualidade com compressão balanceada
log_message("Configurando compressão da imagem para JPEG", 'INFO');
$imagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$imagick->setImageCompressionQuality(85); // Maior qualidade
$imagick->stripImage(); // Remove metadados para reduzir o tamanho
$image_blob = $imagick->getImageBlob();
}
// Salvar a imagem temporariamente
$tmp_img = tempnam($tmp_dir, 'img_') . '.' . $extension;
log_message("Salvando imagem temporária em $tmp_img", 'INFO');
file_put_contents($tmp_img, $image_blob);
chmod($tmp_img, 0666); // Ajustar permissões do arquivo temporário
// Adicionar a imagem ao PDF
log_message("Adicionando imagem ao PDF", 'INFO');
$pdf->AddPage();
$pdf->Image('@' . $image_blob, 15, 40, 180, 160, '', '', 'C', false, 100, '', false, false, 1, false, false, false);
log_message("Imagem adicionada ao PDF", 'INFO');
// Remover a imagem temporária
if (file_exists($tmp_img)) {
log_message("Removendo imagem temporária $tmp_img", 'INFO');
unlink($tmp_img);
} else {
log_message("Imagem temporária $tmp_img não encontrada para remoção", 'WARN');
}
} elseif (in_array($extension, ['pdf'])) {
log_message("Processando PDF $uploaded_file_path", 'INFO');
// Verificar se a extensão Imagick está carregada
if (extension_loaded('imagick')) {
log_message("Imagick está carregado", 'INFO');
// Inicializar Imagick
try {
log_message("Inicializando Imagick para $uploaded_file_path", 'INFO');
$imagick->setResolution(150, 150); // Ajuste a resolução conforme necessário
$imagick->readImage($uploaded_file_path); // Ler todas as páginas do PDF
log_message("PDF lido com sucesso", 'INFO');
// Processar cada página do PDF
$page_count = $imagick->getNumberImages(); // Número total de páginas do PDF
for ($i = 0; $i < $page_count; $i++) {
$imagick->setIteratorIndex($i); // Define a página atual
$imagick->setImageFormat("jpeg"); // Configura o formato como JPEG
// Definir o fundo como branco
$imagick->setImageBackgroundColor('white');
$imagick = $imagick->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
// Reduz a resolução para 1600x1200, mantendo a proporção
$imagick->resizeImage(1600, 1200, Imagick::FILTER_LANCZOS, 1, true);
// Configura as opções de compressão
$imagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$imagick->setImageCompressionQuality(85);
$imagick->stripImage(); // Remove metadados desnecessários
// Obter os dados da imagem
$image_data = $imagick->getImageBlob();
$tmp_img = tempnam($tmp_dir, 'pdf_page_') . '.jpg';
file_put_contents($tmp_img, $image_data); // Salvar página como JPEG temporária
chmod($tmp_img, 0666);
// Adicionar a página como imagem ao novo PDF
$pdf->AddPage();
$pdf->Image($tmp_img, 15, 40, 180, 160, '', '', 'C', false, 100, '', false, false, 1, false, false, false);
// Remover a imagem temporária
unlink($tmp_img);
}
// Limpar recursos do Imagick
$imagick->clear();
$imagick->destroy();
} catch (Exception $e) {
log_message("Erro ao inicializar ou processar imagem com Imagick: " . $e->getMessage(), 'ERROR');
}
} else {
log_message("Imagick não está carregado", 'WARN');
// Se Imagick não estiver disponível, apenas adicionar uma mensagem
$pdf->SetFont('helvetica', '', 12);
$pdf->Write(0, 'Visualização de PDF não suportada.');
}
} else {
log_message("Tipo de arquivo não suportado: $extension", 'WARN');
// Outros tipos de arquivo podem ser adicionados conforme necessidade
$pdf->SetFont('helvetica', '', 12);
$pdf->Write(0, 'Visualização deste tipo de arquivo não está disponível.');
}
} catch (Exception $e) {
log_message("Erro ao processar imagem: " . $e->getMessage(), 'ERROR');
}
// Adicionar uma nova página para as informações
$pdf->AddPage();
// Conteúdo das informações
$html = '<h2>Informações do Documento</h2>';
$html .= '<p><strong>Nome do Arquivo:</strong> ' . htmlspecialchars($document_info['name']) . '</p>';
$html .= '<p><strong>Data de Modificação:</strong> ' . htmlspecialchars($document_info['modification_time']) . '</p>';
$html .= '<p><strong>Data de Envio ao Servidor:</strong> ' . htmlspecialchars($document_info['upload_time']) . '</p>';
$html .= '<p><strong>Data e Hora da Assinatura:</strong> ' . htmlspecialchars($document_info['signature_time']) . ' (UTC-3)</p>';
$html .= '<h3>Checksums</h3>';
$html .= '<ul>';
$html .= '<li><strong>SHA-256:</strong> ' . htmlspecialchars($checksums['sha256']) . '</li>';
$html .= '<li><strong>SHA-512:</strong> ' . htmlspecialchars($checksums['sha512']) . '</li>';
$html .= '<li><strong>MD5:</strong> ' . htmlspecialchars($checksums['md5']) . '</li>';
$html .= '</ul>';
$html .= '<h3>Dados do Dispositivo</h3>';
$html .= '<ul>';
foreach ($device_data as $key => $value) {
$html .= '<li><strong>' . htmlspecialchars((string)$key) . ':</strong> ' . htmlspecialchars((string)$value) . '</li>';
}
$html .= '</ul>';
$orig_link= 'https://validar.martinsevieira.adv.br/uploads/';
$html .= '<h3>Arquivos Originais</h3>';
$html .= '<ul>';
$html .= '<li><a href="' . $orig_link . $document_info['name'] . '">Arquivo Original</a></li>';
$html .= '<li><a href="' . $orig_link . $document_info['name'] . '.ots">Arquivo OTS</a></li>';
$html .= '</ul>';
$html .= '<h3>Arquivo de Timestamp (OTS) em Base64</h3>';
$html .= '<pre>' . htmlspecialchars($ots_base64) . '</pre>';
$pdf->writeHTML($html, true, false, true, false, '');
// Salvar o PDF no servidor
$processed_dir = '/var/www/html/processed/';
if (!is_dir($processed_dir)) {
mkdir($processed_dir, 0777, true);
}
log_message("Salvando PDF no servidor", 'INFO');
$pdf_output_path = $processed_dir . uniqid('prova_') . '.pdf';
$pdf->Output($pdf_output_path, 'F');
$end_time = microtime(true);
log_message("PDF gerado em " . round($end_time - $start_time, 4) . " segundos", 'INFO');
// Limpar recursos do Imagick
$imagick->clear();
$imagick->destroy();
return $pdf_output_path;
}
// Recuperar todos os arquivos pendentes
$mysqli = new mysqli("10.15.0.42", "root", "34641747", "valida");
if ($mysqli->connect_error) {
log_message("Connection failed: " . $mysqli->connect_error, 'ERROR');
die("Connection failed: " . $mysqli->connect_error);
}
log_message("Conexão com o banco de dados estabelecida.", 'INFO');
// Recuperar todos os arquivos pendentes
$result = $mysqli->query("SELECT q.*, cp.port, q.original_location FROM queue q LEFT JOIN client_ports cp ON q.id = cp.queue_id WHERE q.status = 'pending'");
if ($result->num_rows > 0) {
log_message("Encontrados " . $result->num_rows . " arquivos pendentes para processar.", 'INFO');
while ($row = $result->fetch_assoc()) {
// Verificar se o número de processos filhos atingiu o máximo permitido
while (count($childProcesses) >= MAX_CHILDREN) {
// Esperar por qualquer processo filho terminar
$endedPid = pcntl_wait($status);
if ($endedPid > 0) {
unset($childProcesses[$endedPid]);
log_message("Processo filho $endedPid finalizado.", 'INFO');
}
}
// Fork do processo
$pid = pcntl_fork();
if ($pid == -1) {
// Erro ao fork
log_message("Erro ao criar processo filho.", 'ERROR');
} elseif ($pid) {
// Processo pai
$childProcesses[$pid] = true;
log_message("Criado processo filho $pid para o arquivo ID " . $row['id'] . ".", 'INFO');
} else {
// Processo filho
// Fecha a conexão do processo pai antes de iniciar no filho
$mysqli->close();
// Processa o arquivo
process_file($row);
// Finaliza o processo filho
exit(0);
}
}
// Após forçar todos os filhos a serem criados, esperar que terminem
while (count($childProcesses) > 0) {
$endedPid = pcntl_wait($status);
if ($endedPid > 0) {
unset($childProcesses[$endedPid]);
log_message("Processo filho $endedPid finalizado.", 'INFO');
}
}
log_message("Todas as tarefas foram submetidas para processamento.", 'INFO');
} else {
log_message("Nenhum arquivo pendente para processar.", 'INFO');
}
$mysqli->close();
log_message("Processamento da fila finalizado.", 'INFO');
?>
+81
View File
@@ -0,0 +1,81 @@
<?php
// Verificar se o usuário está logado
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit();
}
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Status do Processamento</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.status { margin-top: 20px; }
.status p { margin: 5px 0; }
.completed { color: green; }
.pending { color: orange; }
.processing { color: blue; }
.error { color: red; }
.pagination { margin-top: 20px; text-align: center; }
.pagination a { margin: 0 5px; text-decoration: none; color: #007BFF; }
.pagination a:hover { text-decoration: underline; }
</style>
<script>
function checkStatus(page = 1) {
fetch(`./prova/status_check.php?page_num=${page}`)
.then(response => response.json())
.then(data => {
let statusContainer = document.getElementById('statusContainer');
statusContainer.innerHTML = '';
data.status.forEach(item => {
let p = document.createElement('p');
p.className = item.status;
p.textContent = `Arquivo: ${item.file_path} - Status: ${item.status}`;
statusContainer.appendChild(p);
});
// Paginação
let paginationContainer = document.getElementById('paginationContainer');
paginationContainer.innerHTML = '';
if (data.current_page > 1) {
let prevLink = document.createElement('a');
prevLink.href = `javascript:checkStatus(${data.current_page - 1})`;
prevLink.textContent = '« Anterior';
paginationContainer.appendChild(prevLink);
}
for (let i = 1; i <= data.total_pages; i++) {
let pageLink = document.createElement('a');
pageLink.href = `javascript:checkStatus(${i})`;
if (i === data.current_page) {
pageLink.style.fontWeight = 'bold';
}
pageLink.textContent = i;
paginationContainer.appendChild(pageLink);
}
if (data.current_page < data.total_pages) {
let nextLink = document.createElement('a');
nextLink.href = `javascript:checkStatus(${data.current_page + 1})`;
nextLink.textContent = 'Próximo »';
paginationContainer.appendChild(nextLink);
}
});
}
setInterval(() => checkStatus(), 15000); // Atualizar a cada 15 segundos
window.onload = () => checkStatus();
</script>
</head>
<body>
<div class="container">
<h2>Status do Processamento</h2>
<div id="statusContainer" class="status">
<!-- Status dos arquivos será exibido aqui -->
</div>
<div id="paginationContainer" class="pagination">
<!-- Paginação será exibida aqui -->
</div>
</div>
</body>
</html>
+34
View File
@@ -0,0 +1,34 @@
<?php
// status_check.php
// Conectar ao banco de dados
$mysqli = new mysqli("10.15.0.42", "root", "34641747", "valida");
if ($mysqli->connect_error) {
die("Connection failed: " . $mysqli->connect_error);
}
// Paginação
$files_per_page = 10;
$page = isset($_GET['page_num']) ? (int)$_GET['page_num'] : 1;
$page = max(1, $page);
$offset = ($page - 1) * $files_per_page;
// Recuperar status dos arquivos
$result = $mysqli->query("SELECT file_path, status FROM queue ORDER BY created_at DESC LIMIT $files_per_page OFFSET $offset");
$status = [];
while ($row = $result->fetch_assoc()) {
$status[] = $row;
}
// Contar o total de arquivos para a paginação
$total_result = $mysqli->query("SELECT COUNT(*) AS total FROM queue");
$total_files = $total_result->fetch_assoc()['total'];
$total_pages = ceil($total_files / $files_per_page);
$mysqli->close();
header('Content-Type: application/json');
echo json_encode(['status' => $status, 'current_page' => $page, 'total_pages' => $total_pages]);
?>
+133
View File
@@ -0,0 +1,133 @@
<?php
// Configurações iniciais
date_default_timezone_set('America/Araguaina');
// Conectar ao banco de dados
$mysqli = new mysqli("10.15.0.42", "root", "34641747", "valida");
if ($mysqli->connect_error) {
die("Connection failed: " . $mysqli->connect_error);
}
// Diretório de upload
$upload_dir = '/var/www/html/uploads/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0777, true);
}
// Tipos de arquivos permitidos
$allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
$max_file_size = 10 * 1024 * 1024; // 10MB
// Ignorar autenticação para esta página
// if (basename($_SERVER['PHP_SELF']) == 'upload.php') {
// // Ignorar autenticação para esta página
// } else {
// // ...código de autenticação existente...
// }
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_FILES['files'])) {
$files = $_FILES['files'];
$modification_times = isset($_POST['modification_times']) ? explode(',', $_POST['modification_times']) : [];
// Capturar informações adicionais
$user_agent = isset($_POST['user_agent']) ? $_POST['user_agent'] : 'Desconhecido';
$language = isset($_POST['language']) ? $_POST['language'] : 'Desconhecido';
$viewport_width = isset($_POST['viewport_width']) ? intval($_POST['viewport_width']) : 0;
$viewport_height = isset($_POST['viewport_height']) ? intval($_POST['viewport_height']) : 0;
$ip_address = $_SERVER['REMOTE_ADDR'];
$host_name = gethostbyaddr($ip_address);
$access_time = date("Y-m-d H:i:s"); // Formato padrão MySQL
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'Desconhecido';
$request_method = $_SERVER['REQUEST_METHOD'];
$server_software = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'Desconhecido';
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'Desconhecido';
$connection = isset($_SERVER['HTTP_CONNECTION']) ? $_SERVER['HTTP_CONNECTION'] : 'Desconhecido';
$client_port = isset($_SERVER['REMOTE_PORT']) ? intval($_SERVER['REMOTE_PORT']) : 0;
for ($i = 0; $i < count($files['name']); $i++) {
$file_name = basename($files['name'][$i]);
$file_tmp = $files['tmp_name'][$i];
$file_size = $files['size'][$i];
$file_type = $files['type'][$i];
$file_error = $files['error'][$i];
$file_path = $upload_dir . $file_name;
// Validações
if ($file_error !== UPLOAD_ERR_OK) {
continue;
}
if ($file_size > $max_file_size) {
continue;
}
if (!in_array($file_type, $allowed_types)) {
continue;
}
// Movendo o arquivo
if (move_uploaded_file($file_tmp, $file_path)) {
// Ajustar a data de modificação usando touch()
if (isset($modification_times[$i])) {
$mod_time = intval($modification_times[$i] / 1000); // Convertendo de milissegundos para segundos
touch($file_path, $mod_time);
}
// Gerar hash do arquivo para integridade
$file_hash = hash_file('sha256', $file_path);
// Preparar inserção na tabela queue
$stmt = $mysqli->prepare("INSERT INTO queue (file_path, user_agent, ip_address, host_name, access_time, language, referer, request_method, server_software, protocol, connection, viewport_width, viewport_height, file_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
if (!$stmt) {
unlink($file_path);
continue;
}
$stmt->bind_param(
"ssssssssssssss",
$file_path,
$user_agent,
$ip_address,
$host_name,
$access_time,
$language,
$referer,
$request_method,
$server_software,
$protocol,
$connection,
$viewport_width,
$viewport_height,
$file_hash
);
if ($stmt->execute()) {
$queue_id = $stmt->insert_id;
} else {
unlink($file_path);
$stmt->close();
continue;
}
$stmt->close();
// Adicionar entrada na tabela client_ports
$stmt_port = $mysqli->prepare("INSERT INTO client_ports (queue_id, port) VALUES (?, ?)");
if (!$stmt_port) {
continue;
}
$stmt_port->bind_param("ii", $queue_id, $client_port);
if ($stmt_port->execute()) {
} else {
}
$stmt_port->close();
} else {
}
}
}
}
$mysqli->close();
header("Location: /index.php?page=status");
exit();
?>
+211
View File
@@ -0,0 +1,211 @@
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Upload de Arquivos</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?php
// Verificação de folhas de estilo previamente aplicadas
$hasStylesheet = false;
// Verificar se há elementos <link> ou <style> no documento
ob_start();
?>
<script>
document.addEventListener("DOMContentLoaded", function() {
var hasStylesheet = document.querySelector('link[rel="stylesheet"], style') !== null;
var xhr = new XMLHttpRequest();
xhr.open("POST", "", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("hasStylesheet=" + hasStylesheet);
});
</script>
<?php
$script = ob_get_clean();
echo $script;
if (isset($_POST['hasStylesheet']) && $_POST['hasStylesheet'] === 'true') {
$hasStylesheet = true;
}
if (!$hasStylesheet) {
echo '<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 500px;
text-align: center;
}
h2 {
margin-bottom: 20px;
color: #333;
}
label {
display: block;
margin-bottom: 10px;
color: #555;
}
.custom-file-input {
position: relative;
display: inline-block;
width: 100%;
height: 40px;
margin-bottom: 20px;
}
.custom-file-input input[type="file"] {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
.custom-file-input::before {
content: "Escolher arquivos";
display: inline-block;
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
text-align: center;
width: 100%;
height: 100%;
line-height: 20px;
}
.custom-file-input input[type="file"]:focus + ::before {
outline: 1px dotted #000;
outline: -webkit-focus-ring-color auto 5px;
}
.custom-file-input input[type="file"]::after {
content: "Nenhum arquivo escolhido";
display: block;
margin-top: 10px;
color: #555;
}
button {
background-color: #007bff;
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
margin-top: 10px;
}
button:hover {
background-color: #0056b3;
}
@media (max-width: 600px) {
body {
height: auto;
padding: 20px;
}
.container {
padding: 15px;
width: 100%;
}
h2 {
font-size: 18px;
}
button {
width: 100%;
padding: 12px;
font-size: 14px;
}
.custom-file-input::before {
padding: 12px;
font-size: 14px;
}
}
</style>';
}
?>
<script>
function addViewportDimensions() {
var form = document.getElementById('uploadForm');
var vw = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var vh = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var inputWidth = document.createElement('input');
inputWidth.type = 'hidden';
inputWidth.name = 'viewport_width';
inputWidth.value = vw;
form.appendChild(inputWidth);
var inputHeight = document.createElement('input');
inputHeight.type = 'hidden';
inputHeight.name = 'viewport_height';
inputHeight.value = vh;
form.appendChild(inputHeight);
var userAgent = navigator.userAgent;
var inputUserAgent = document.createElement('input');
inputUserAgent.type = 'hidden';
inputUserAgent.name = 'user_agent';
inputUserAgent.value = userAgent;
form.appendChild(inputUserAgent);
var language = navigator.language || navigator.userLanguage;
var inputLanguage = document.createElement('input');
inputLanguage.type = 'hidden';
inputLanguage.name = 'language';
inputLanguage.value = language;
form.appendChild(inputLanguage);
var files = document.getElementById('files').files;
var modificationTimes = [];
for (let i = 0; i < files.length; i++) {
const file = files[i];
const lastModified = file.lastModified ? file.lastModified : '';
modificationTimes.push(lastModified);
}
var inputModification = document.createElement('input');
inputModification.type = 'hidden';
inputModification.name = 'modification_times';
inputModification.value = modificationTimes.join(',');
form.appendChild(inputModification);
}
window.onload = function() {
var form = document.getElementById('uploadForm');
form.onsubmit = function(event) {
addViewportDimensions();
}
var fileInput = document.getElementById('files');
fileInput.addEventListener('change', function() {
var existingInputs = document.querySelectorAll('input[name="modification_times"]');
existingInputs.forEach(function(input) {
input.remove();
});
});
}
</script>
</head>
<body>
<div class="container">
<h2>Upload de Arquivos</h2>
<form id="uploadForm" action="./upload.php" method="post" enctype="multipart/form-data">
<label for="files">Selecione os arquivos para autenticar:</label><br><br>
<input type="file" name="files[]" id="files" multiple required><br><br>
<button type="submit">Autenticar</button>
</form>
</div>
</body>
</html>