Skip to content

Commit

Permalink
Merge branch 'main' into add_missing_dependabot
Browse files Browse the repository at this point in the history
  • Loading branch information
melroy89 authored Sep 25, 2024
2 parents 02e0629 + 47427d9 commit 61b13bb
Show file tree
Hide file tree
Showing 5 changed files with 435 additions and 28 deletions.
70 changes: 44 additions & 26 deletions src/Service/ActivityPub/ApHttpClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,27 +89,27 @@ public function getActivityObject(string $url, bool $decoded = true): array|stri
private function getActivityObjectImpl(string $url): ?string
{
$this->logger->debug("ApHttpClient:getActivityObject:url: $url");

$client = new CurlHttpClient();
$content = null;
try {
$r = $client->request('GET', $url, [
$client = new CurlHttpClient();
$response = $client->request('GET', $url, [
'max_duration' => self::MAX_DURATION,
'timeout' => self::TIMEOUT,
'headers' => $this->getInstanceHeaders($url),
]);

$statusCode = $r->getStatusCode();
$statusCode = $response->getStatusCode();
// Accepted status code are 2xx or 410 (used Tombstone types)
if (!str_starts_with((string) $statusCode, '2') && 410 !== $statusCode) {
// Do NOT include the content in the error message, this will be often a full HTML page
throw new InvalidApPostException("Invalid status code while getting: $url : $statusCode");
// Do NOT include the response content in the error message, this will be often a full HTML page
throw new InvalidApPostException("Invalid status code while getting: $url, status code: $statusCode");
}

// Read also non-OK responses (like 410) by passing 'false'
$content = $r->getContent(false);
$content = $response->getContent(false);
$this->logger->debug('ApHttpClient:getActivityObject:url: {url} - content: {content}', ['url' => $url, 'content' => $content]);
} catch (\Exception $e) {
$this->logRequestException($r, $url, 'ApHttpClient:getActivityObject', $e);
$this->logRequestException($response, $url, 'ApHttpClient:getActivityObject', $e);
}

return $content;
Expand Down Expand Up @@ -171,19 +171,19 @@ public function getWebfingerObject(string $url): ?array
private function getWebfingerObjectImpl(string $url): ?string
{
$this->logger->debug("ApHttpClient:getWebfingerObject:url: $url");
$r = null;
$response = null;
try {
$client = new CurlHttpClient();
$r = $client->request('GET', $url, [
$response = $client->request('GET', $url, [
'max_duration' => self::MAX_DURATION,
'timeout' => self::TIMEOUT,
'headers' => $this->getInstanceHeaders($url, null, 'get', ApRequestType::WebFinger),
]);
} catch (\Exception $e) {
$this->logRequestException($r, $url, 'ApHttpClient:getWebfingerObject', $e);
$this->logRequestException($response, $url, 'ApHttpClient:getWebfingerObject', $e);
}

return $r->getContent();
return $response->getContent();
}

private function getActorCacheKey(string $apProfileId): string
Expand Down Expand Up @@ -317,8 +317,8 @@ private function getCollectionObjectImpl(string $apAddress): ?string
$statusCode = $response->getStatusCode();
// Accepted status code are 2xx or 410 (used Tombstone types)
if (!str_starts_with((string) $statusCode, '2') && 410 !== $statusCode) {
// Do NOT include the content in the error message, this will be often a full HTML page
throw new InvalidApPostException("Invalid status code while getting: $apAddress : $statusCode");
// Do NOT include the response content in the error message, this will be often a full HTML page
throw new InvalidApPostException("Invalid status code while getting: $apAddress, status code: $statusCode");
}
} catch (\Exception $e) {
$this->logRequestException($response, $apAddress, 'ApHttpClient:getCollectionObject', $e);
Expand All @@ -328,6 +328,16 @@ private function getCollectionObjectImpl(string $apAddress): ?string
return $response->getContent();
}

/**
* Helper function for logging get/post/.. requests to the error & debug log with additional info.
*
* @param ResponseInterface|null $response Optional response object
* @param string $requestUrl Full URL of the request
* @param string $requestType an additional string where the error happened in the code
* @param \Exception $e Error object
*
* @throws InvalidApPostException rethrows the error
*/
private function logRequestException(?ResponseInterface $response, string $requestUrl, string $requestType, \Exception $e): void
{
if (null !== $response) {
Expand All @@ -341,7 +351,7 @@ private function logRequestException(?ResponseInterface $response, string $reque

// Often 400, 404 errors just return the full HTML page, so we don't want to log the full content of them
// We truncate the content to 200 characters max.
$this->logger->error('{type} get fail: {address}, ex: {e}: {msg}. Truncated content: {content}', [
$this->logger->error('{type} failed: {address}, ex: {e}: {msg}. Truncated content: {content}', [
'type' => $requestType,
'address' => $requestUrl,
'e' => \get_class($e),
Expand All @@ -354,7 +364,7 @@ private function logRequestException(?ResponseInterface $response, string $reque
'content' => $content,
]);
}
throw $e;
throw $e; // re-throw the exception
}

/**
Expand All @@ -379,20 +389,28 @@ public function post(string $url, User|Magazine $actor, ?array $body = null): vo
return;
}

$jsonBody = json_encode($body ?? []);

$this->logger->debug("ApHttpClient:post:url: $url");
$this->logger->debug('ApHttpClient:post:body '.json_encode($body ?? []));
$this->logger->debug("ApHttpClient:post:body $jsonBody");

// Set-up request
$client = new CurlHttpClient();
$response = $client->request('POST', $url, [
'max_duration' => self::MAX_DURATION,
'timeout' => self::TIMEOUT,
'body' => json_encode($body),
'headers' => $this->getHeaders($url, $actor, $body),
]);
try {
$client = new CurlHttpClient();
$response = $client->request('POST', $url, [
'max_duration' => self::MAX_DURATION,
'timeout' => self::TIMEOUT,
'body' => $jsonBody,
'headers' => $this->getHeaders($url, $actor, $body),
]);

if (!str_starts_with((string) $response->getStatusCode(), '2')) {
throw new InvalidApPostException("Post fail: $url, ".substr($response->getContent(false), 0, 1000).' '.json_encode($body));
$statusCode = $response->getStatusCode();
if (!str_starts_with((string) $statusCode, '2')) {
// Do NOT include the response content in the error message, this will be often a full HTML page
throw new InvalidApPostException("Post failed: $url, status code: $statusCode, request body: $jsonBody");
}
} catch (\Exception $e) {
$this->logRequestException($response, $url, 'ApHttpClient:post', $e);
}

// build cache
Expand Down
2 changes: 2 additions & 0 deletions translations/messages.de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -938,3 +938,5 @@ disabled: Deaktiviert
downvotes_mode: Reduzieren Modus
hidden: Versteckt
enabled: Aktiviert
toolbar.spoiler: Spoiler
comment_not_found: Kommentar nicht gefunden
4 changes: 4 additions & 0 deletions translations/messages.fr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -742,3 +742,7 @@ two_factor_authentication: Authentification à deux facteurs
admin_users_suspended: Suspendus
admin_users_banned: Bannis
admin_users_inactive: Inactifs
enabled: Activé
disabled: Désactivé
hidden: Masqué
magazine_deletion: Suppression de magazine
141 changes: 139 additions & 2 deletions translations/messages.pt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ activity: Atividade
cover: Capa
related_posts: Postagens relacionadas
random_posts: Postagens aleatórias
federated_user_info: O perfil do servidor federado pode estar incompleto.
go_to_original_instance: Navega mais na instância federada.
federated_user_info: Esse perfil é de um servidor federado e pode estar incompleto.
go_to_original_instance: Visualizar na instância remota
empty: Vazio
subscribe: Subscrever
unsubscribe: Cancelar subscrição
Expand Down Expand Up @@ -336,3 +336,140 @@ set_magazines_bar: Barra de magazines
set_magazines_bar_desc: adicione os nomes dos magazines após a virgula
set_magazines_bar_empty_desc: se o espaço estiver vazio, magazines ativos serão mostrados
na barra
subscribe_for_updates: Inscreva-se para começar a receber atualizações.
remove_media: Remover mídia
unmark_as_adult: Desmarcar como NSFW
flash_mark_as_adult_success: A publicação foi marcada com sucesso como NSFW.
delete_account: Excluir conta
menu: Menu
flash_unmark_as_adult_success: A publicação foi desmarcada com sucesso como NSFW.
unban_hashtag_btn: Desbanir Hashtag
unban_hashtag_description: Ao "desbanir" uma hashtag, novas publicações com essa hashtag
poderão ser criadas. As publicações existentes com essa hashtag não serão mais ocultadas.
dynamic_lists: Listas dinâmicas
banned_instances: Instâncias banidas
report_issue: Relatar problema
disabled: Desativado
hidden: Oculto
enabled: Ativado
default_theme: Tema padrão
ban_hashtag_description: Ao banir uma hashtag, você impedirá a criação de publicações
com essa hashtag, além de ocultar as publicações existentes com essa hashtag.
Your account is not active: Sua conta não está ativa.
firstname: Nome
reload_to_apply: Recarregar a página para aplicar as alterações
marked_for_deletion_at: Marcado para ser excluído em %date%
mark_as_adult: Marcar como NSFW
ban_account: Banir conta
header_logo: Logotipo do cabeçalho
filter.fields.only_names: Somente nomes
filter.fields.names_and_descriptions: Nomes e descrições
unban_account: Desbanir conta
sidebar: Barra lateral
captcha_enabled: Captcha ativado
browsing_one_thread: Você está navegando apenas em um tópico da discussão! Todos os
comentários estão disponíveis na página do post.
return: Retornar
filter.adult.hide: Ocultar NSFW
filter.adult.show: Mostrar NSFW
filter.adult.only: Somente NSFW
your_account_has_been_banned: Sua conta foi banida
send: Enviar
sticky_navbar_help: A barra de navegação permanecerá na parte superior da página quando
você rolar para baixo.
toolbar.italic: Itálico
kbin_promo_title: Crie sua própria instância
kbin_intro_title: Explorar o Fediverso
infinite_scroll_help: Carregar automaticamente mais conteúdo quando chegar ao final
da página.
subscribers_count: '{0}Inscritos|{1}Inscrito|]1,Inf[ Inscritos'
followers_count: '{0}Seguidores|{1}Seguidor|]1,Inf[ Seguidores'
marked_for_deletion: Marcado para ser excluído
sort_by: Ordenar por
filter_by_subscription: Filtrar por assinatura
filter_by_federation: Filtrar por status da federação
kbin_bot: Agente Mbin
toolbar.bold: Negrito
Your account has been banned: Sua conta foi banida.
active_users: Pessoas ativas
password_confirm_header: Confirme sua solicitação de alteração de senha.
toolbar.strikethrough: Riscado
Password is invalid: Senha inválida.
toolbar.header: Cabeçalho
oauth2.grant.domain.all: Assine ou bloqueie domínios e visualize os domínios que você
assinou ou bloqueou.
downvotes_mode: Modo de votos negativos
change_downvotes_mode: Alterar o modo de votos negativos
errors.server500.description: Desculpe, algo deu errado aqui do nosso lado. Se você
continuar a ver esse erro, tente entrar em contato com o proprietário da instância.
Se essa instância não estiver funcionando, verifique %link_start%outras instâncias
do Mbin%link_end% enquanto isso, até que o problema seja resolvido.
errors.server404.title: 404 Não encontrado
errors.server403.title: 403 Proibido
email.delete.title: Pedido de exclusão da conta do usuário
block: Bloquear
always_disconnected_magazine_info: Esta revista não está recebendo atualizações.
from: de
resend_account_activation_email_success: Se houver uma conta associada a esse e-mail,
enviaremos um novo e-mail de ativação.
resend_account_activation_email_description: Digite o endereço de e-mail associado
à sua conta. Nós te enviaremos outro e-mail de ativação.
custom_css: CSS Personalizado
ignore_magazines_custom_css: Ignorar o CSS personalizado das revistas
oauth.consent.title: Formulário de Consentimento OAuth2
oauth.consent.app_requesting_permissions: gostaria de realizar as seguintes ações
em seu nome
oauth.consent.to_allow_access: Para permitir esse acesso, clique no botão 'Permitir'
abaixo
oauth.consent.allow: Permitir
oauth.client_identifier.invalid: ID de cliente OAuth inválido!
oauth2.grant.moderate.magazine.ban.delete: Desbanir usuários em suas revistas moderadas.
unblock: Desbloquear
private_instance: Forçar os usuários a fazer login antes de poderem acessar qualquer
conteúdo
oauth2.grant.moderate.magazine.list: Leia uma lista de suas revistas moderadas.
oauth2.grant.moderate.magazine.reports.all: Gerencie denúncias nas suas revistas moderadas.
oauth2.grant.moderate.magazine_admin.all: Crie, edite ou exclua suas próprias revistas.
oauth2.grant.moderate.magazine.reports.read: Leia denúncias nas suas revistas moderadas.
oauth2.grant.moderate.magazine.trash.read: Veja o conteúdo descartado em suas revistas
moderadas.
oauth2.grant.moderate.magazine_admin.create: Crie novas revistas.
oauth2.grant.moderate.magazine_admin.edit_theme: Edite o CSS personalizado de qualquer
uma de suas revistas.
oauth2.grant.subscribe.general: Assine ou siga qualquer revista, domínio ou usuário
e veja as revistas, domínios e usuários nos quais você se inscreveu.
oauth2.grant.moderate.magazine_admin.update: Edite as regras, a descrição, o status
NSFW ou o ícone de qualquer uma das suas revistas.
oauth2.grant.domain.block: Bloqueie ou desbloqueie domínios e visualize os domínios
que você bloqueou.
email.delete.description: O usuário seguinte solicitou que sua conta fosse excluída
resend_account_activation_email: Reenviar o e-mail de ativação da conta
errors.server429.title: 429 Solicitações em excesso
email_confirm_button_text: Confirme sua solicitação de alteração de senha
email_confirm_link_help: Como alternativa, você pode copiar e colar o seguinte em
seu navegador
oauth.consent.app_has_permissions: já pode executar as seguintes ações
oauth.client_not_granted_message_read_permission: Este aplicativo não recebeu permissão
para ler suas mensagens.
restrict_oauth_clients: Restringir a criação de clientes OAuth2 aos administradores
oauth2.grant.moderate.magazine.reports.action: Aceite ou rejeite denúncias em suas
revistas moderadas.
oauth2.grant.admin.all: Execute ações administrativas em sua instância.
oauth2.grant.read.general: Leia todo o conteúdo ao qual você tem acesso.
resend_account_activation_email_error: Houve um problema ao enviar esta solicitação.
Talvez não tenha uma conta associada a esse e-mail ou talvez ele já esteja ativado.
oauth2.grant.domain.subscribe: Assine ou cancele a assinatura de domínios e visualize
os domínios a que você se inscreveu.
oauth2.grant.moderate.magazine_admin.delete: Exclua qualquer uma de suas revistas.
oauth2.grant.block.general: Bloqueie ou desbloqueie qualquer revista, domínio ou usuário
e visualize as revistas, os domínios e os usuários que você bloqueou.
comment_not_found: Comentário não encontrado
oauth.consent.deny: Recusar
oauth2.grant.moderate.magazine_admin.moderators: Adicionar ou remover moderadores
de qualquer uma de suas revistas.
oauth2.grant.moderate.magazine_admin.badges: Crie ou remova selos de suas revistas
próprias.
disconnected_magazine_info: Esta revista não está recebendo atualizações (última atividade
%dias% dia(s) atrás).
resend_account_activation_email_question: Conta inativa?
oauth.consent.grant_permissions: Conceder permissões
Loading

0 comments on commit 61b13bb

Please sign in to comment.