Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

110 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MacHTTrack

Ícone do MacHTTrack

Interface gráfica nativa de macOS para o HTTrack Website Copier.

O HTTrack copia sites inteiros para o disco, mas no macOS só existe como linha de comando — o WebHTTrack do mundo Unix serve um wizard HTML num mini-servidor e depende do navegador. O MacHTTrack é um app Mac de verdade: SwiftUI, uma janela, sidebar de sites, progresso ao vivo.

Completa a família do projeto: WinHTTrack no Windows, WebHTTrack no Unix, MacHTTrack no macOS.

Status: versão 1.0 — baixe o .app. Adicione uma URL, escolha a pasta, acompanhe o progresso ao vivo, pare e retome. O httrack-agent espelha pela linha de comando e reporta progresso em JSON Lines; toda a lógica mora no app SwiftUI. Detalhes de arquitetura no design doc.

Captura de tela

O MacHTTrack espelhando um site: sidebar de sites à esquerda, progresso ao vivo e log à direita

O que faz

  • Espelhar sites — URL, pasta de destino, profundidade e limite de velocidade
  • Configurar por site, em abas no estilo WinHTTrack — regras de incluir/excluir (-*.zip, +*.pdf), robots.txt, user-agent e referer
  • Rede e autenticação — proxy (com usuário e senha) e login HTTP do site, guardados no Keychain, nunca no sites.json
  • Acompanhar e controlar — progresso ao vivo, conexões ativas e log; parar e retomar de onde parou
  • Gerir a lista — nome amigável para cada site e excluir, opcionalmente apagando a pasta do espelho

Um download por vez, por ora. No radar: vários espelhos simultâneos e mais gestão das cópias (tamanho em disco, revelar no Finder, abrir no navegador).

Fora do escopo: busca dentro do conteúdo baixado, distribuição pública (assinatura Developer ID, notarização, App Store), Windows e Linux.

Como funciona

Um único .app, sem instalador e sem dependência externa. Dentro dele, dois executáveis:

MacHTTrack.app/Contents/MacOS/
├── MacHTTrack        ← app SwiftUI
└── httrack-agent     ← motor: libhttrack.a + OpenSSL, tudo estático

O app lança um httrack-agent por download. As opções do mirror vão por argv, na mesma sintaxe da CLI do HTTrack; só os segredos vão por stdin, como linhas CHAVE=valor, para não ficarem visíveis no ps. O progresso volta por stdout em JSON Lines, alimentado pelos callbacks loop e filesave da libhttrack.

Rodando o agente na mão

O agente é exercitável inteiramente pelo terminal — é assim por design. O stdin precisa ser fechado: os segredos são lidos até EOF, antes da primeira linha de saída, então sem redirecionamento o processo fica parado esperando, sem emitir nada (o agente avisa no stderr quando percebe que o stdin é um terminal).

# Sem segredo nenhum — repare no </dev/null.
agent/httrack-agent "http://example.com/" -O /tmp/espelho -r2 --quiet </dev/null

# Com credencial HTTP: pelo stdin, nunca no argv (o `ps` mostra argv).
printf 'HTTP_USER=alice\nHTTP_PASSWORD=hunter2\n' \
  | agent/httrack-agent "http://example.com/privado/" -O /tmp/espelho -r2 --quiet

# Atrás de um proxy que exige autenticação.
printf 'PROXY_USER=bob\nPROXY_PASSWORD=s3cr3t\n' \
  | agent/httrack-agent "http://example.com/" -P "http://proxy.local:3128" \
      -O /tmp/espelho -r2 --quiet

Chaves aceitas no stdin: HTTP_USER, HTTP_PASSWORD, PROXY_USER, PROXY_PASSWORD — desconhecidas são ignoradas de propósito, para o app poder acrescentar novas sem quebrar um agente antigo. A credencial HTTP é registrada para o host da URL semente; ela precisa, portanto, trazer esquema (http:/https:, com o // opcional).

O agente recusa a execução (código 2, um error de nível fatal no protocolo, hts_main2() nunca roda) quando não consegue decidir com segurança de quem são os bytes da autoridade de uma URL semente — tipicamente uma credencial com /, ?, # ou @ não codificado. A mensagem diz qual codificação usar (%2F, %3F, %23, %40). Vale inclusive para uma URL credenciada com @ no caminho ou na query (http://user:pass@host/p?x=a@b → escreva x=a%40b). O raciocínio inteiro, ramo por ramo, está em report_strip_argv_credentials() (agent/agent_report.c).

Cada linha da saída é um JSON: ready primeiro, done por último, progress/file/error no meio — com a exceção das falhas de arranque, documentadas em "Protocolo do agente" no design doc.

Por que processos separados? A API do HTTrack é process-global em vários pontos — httrack-library.h:191-192 avisa que hts_get_stats() devolve um static "not thread-safe and overwritten by the next call". Dois mirrors no mesmo processo corrompem estado. Um processo por mirror resolve isso por construção, isola falhas do C e mantém a UI responsiva.

Requisitos

  • macOS 26 ou superior, Apple Silicon
  • Xcode 26+
  • Homebrew com openssl@3 (só para construir; o .app resultante não depende do Homebrew)
  • autoconf, automake, libtool (para construir a libhttrack)

Build

git submodule update --init --recursive
./scripts/build-libhttrack.sh     # libhttrack.a estática
make -C agent                     # httrack-agent
make -C agent check               # suíte do agente (5 conjuntos)
swift test                        # suíte do app
./scripts/assemble-app.sh         # monta build/MacHTTrack.app
open build/MacHTTrack.app

O make roda scripts/check-linkage.sh automaticamente — se o agente ganhar qualquer dependência fora de /usr/lib, o build falha.

O make -C agent check roda a suíte inteira do agente: os dois testes unitários (test-json, test-secrets) e as três suítes de shell (tests/integration.sh, tests/test_stop.sh, tests/test_tls.sh). As de shell sobem servidores HTTP/HTTPS locais com python3 e levam alguns minutos.

A dependência C é construída estaticamente e embutida no binário. O ponto crítico, que o scripts/build-libhttrack.sh e o agent/Makefile já resolvem: os .a do OpenSSL devem ser passados por caminho absoluto. O flag --disable-shared governa a libhttrack, não o OpenSSL — com -lssl -lcrypto o linker acha .dylib e .a no mesmo diretório e prefere a dinâmica, prendendo o binário a /opt/homebrew/....

Verificação manual do mesmo que o check-linkage.sh faz — só devem aparecer bibliotecas de /usr/lib:

otool -L agent/httrack-agent

Estado da validação

Em macOS 26.6 / Apple Silicon / Xcode 26.6, sobre o HTTrack 3.49.14:

Verificação Resultado
configure + make exit 0; libhttrack.a com 4,0 MB
Link estático /usr/lib/libz, /usr/lib/libiconv, libSystem. 6,0 MB
Execução HTTrack version 3.49-14
HTTPS real Espelhou https://example.com/ sem erros nem avisos
make -C agent check Cinco suítes verdes: test-json, test-secrets, integração, parada/retomada e TLS
swift test 127 testes verdes, sem avisos — inclui um fim a fim que espelha, para e retoma contra o servidor de fixtures
scripts/assemble-app.sh MacHTTrack.app monta e assina; espelha, para e retoma pela interface

Aviso de segurança: TLS não autentica

O HTTrack não valida certificados TLS — é decisão do upstream (htslib.c:5731: "no cert verify, by design"), e nenhuma função de verificação aparece em src/*.c.

Na prática: https:// garante que o tráfego é criptografado, mas não que o servidor do outro lado seja quem diz ser. Um intermediário com certificado autoassinado é aceito em silêncio. Por isso o MacHTTrack não exibe cadeado nem usa a palavra "seguro" em lugar nenhum da interface — seria uma promessa que o motor não cumpre.

Esse comportamento está travado por agent/tests/test_tls.sh: se uma versão futura do motor passar a rejeitar certificados autoassinados, o teste falha — não porque rejeitar seja errado, mas porque a exigência de interface acima deixaria de valer e precisa ser revista, não descoberta por acaso.

Licença

O HTTrack é GPL-3.0-or-later. Este projeto o vincula estaticamente, então herda a GPL-3.0-or-later.

About

Interface gráfica nativa de macOS para o HTTrack Website Copier

Topics

Resources

Stars

Watchers

Forks

Releases

Contributors

Languages