web-dev-qa-db-fra.com

wp_remote_post ne fonctionne pas avec plus de 1024 octets dans le corps

Ce dont j'ai besoin

Je travaille avec une API tierce (pour les besoins de cette question, peu importe laquelle) et il est nécessaire d'envoyer une demande POST à un service externe.

J'essaie d'utiliser wp_remote_post pour obtenir ce dont j'ai besoin, mais il semble y avoir une limite à la quantité de données qu'il peut envoyer dans le corps de sa demande.

Le problème auquel je suis confronté

Il est envoyé uniquement si le corps contient 1024 caractères maximum. Un caractère de plus et la demande (apparemment) n'est pas envoyée.

Déboguer

J'essaie de résoudre le problème en utilisant ngrok pour écouter les demandes POST à $url, et en définissant manuellement $body comme chaîne de "bla bla bla (...)". Ils ne s'affichent que lorsque $body contient 1024 caractères ou moins. Je ne reçois pas d'erreur 5xx ni aucun autre message d'erreur. En fait, is_wp_error( $response ) renvoie false.

Cependant, si j'utilise un outil tel que Postman pour générer une demande POST similaire en dehors de WP avec plus de 1024 caractères dans son corps, ngrok la reçoit. ça va.


  • WP -> corps de la requête inférieur à 1024 octets -> ngrok = OK
  • WP -> corps de la requête supérieur à 1024 octets -> ngrok = ??
  • Postman -> Corps de la requête inférieur à 1024 octets -> ngrok = OK
  • Postman -> Corps de la requête supérieur à 1024 octets -> ngrok = OK

Ce que j'ai essayé

  • Envoi de la même requête depuis l’extérieur de WordPress avec plus de 1024 octets sur son corps: cela fonctionne.
  • Une toute nouvelle installation WordPress sans plug-ins et un thème par défaut (vingt-sept ans): ça ne marche pas.
  • Essayer sur un autre PC, avec la dernière installation de Fedora, le dernier noyau Linux, la dernière version de Firefox, la dernière version de Docker: ne fonctionnait pas.

Ma configuration

Tous les tests sont effectués sur ma machine locale. WordPress 4.9.5 s'exécute dans un conteneur Docker avec l'image WordPress par défaut. Il utilise la configuration par défaut non modifiée, à l'exception des lignes in php personnalisées suivantes:

file_uploads = On
memory_limit = 64M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 600

Le code

  $response = wp_remote_post( $url,
    array(
      'timeout' => 60,
      'redirection' => 5,
      'blocking' => true,
      'headers' => array(
        'Content-Type' => 'application/json',
      ),
      'body' => 'bla bla (...)' // fails if larger than 1024
    )
  );

  if ( is_wp_error( $response ) ) {
    $error_message = $response->get_error_message();
    echo "Something went wrong: $error_message";
  } else { echo "Request sent"; }
2
That Brazilian Guy

Si vous utilisez le transport CURL, des problèmes mineurs d’envoi de POST de plus de 1024 caractères sont parfois rencontrés. Plus d'infos ici:

https://stackoverflow.com/questions/463144/php-http-post-fails-when-curl-data-1024

La solution suggérée consiste à envoyer un en-tête Expect: vide. Vous pouvez le faire en modifiant votre code comme suit:

$response = wp_remote_post( $url,
    array(
      'timeout' => 60,
      'redirection' => 5,
      'blocking' => true,
      'headers' => array(
        'Content-Type' => 'application/json',
        'Expect' => '',
      ),
      'body' => 'bla bla (...)' // fails if larger than 1024
    )
  );

Edit: plus d'infos:

Certaines versions de curl et PHP, lorsque vous insérez plus de 1024 caractères dans le corps, envoient d’abord les en-têtes, puis un en-tête "Expect: 100-continue". Un serveur Web qui reçoit ceci doit alors répondre avec un statut 100 Continuer pour que le client continue à envoyer le reste du corps.

Si vous utilisez un vrai serveur Web, il enverra cette réponse pour recevoir le reste du message. Certains serveurs Web plus anciens ne l'ont pas fait, d'où la solution proposée dans la question précédente.

Je ne sais pas ce que ngrok est, mais je parie qu'il ne répond pas comme un serveur Web normal ici. Sans que ce serveur dise de continuer le POST, curl l'attend pour le faire. Il finit par expirer.

5
Otto