From 6a9dfe654d01c69ade1296d96b04d8bf7d115fe6 Mon Sep 17 00:00:00 2001 From: Ryan Cramer Date: Fri, 8 Jul 2022 09:43:14 -0400 Subject: [PATCH] Update in WireHttp to correct issue where curl POST method sometimes did not work due to 'expect' header that CURL adds to some requests, plus an extra boundary CURL adds to content-type --- wire/core/WireDatabasePDO.php | 2 +- wire/core/WireHttp.php | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/wire/core/WireDatabasePDO.php b/wire/core/WireDatabasePDO.php index b4c556e6..8e72ed4a 100644 --- a/wire/core/WireDatabasePDO.php +++ b/wire/core/WireDatabasePDO.php @@ -976,7 +976,7 @@ class WireDatabasePDO extends Wire implements WireDatabase { * * #pw-group-custom * - * @param string $sql Query (string) to log, boolean true to reset/start query logging, boolean false to stop query logging + * @param string|bool $sql Query (string) to log, boolean true to reset/start query logging, boolean false to stop query logging * @param string $note Any additional debugging notes about the query * @return array|bool|int Returns query log array, boolean true on success, boolean false if not * diff --git a/wire/core/WireHttp.php b/wire/core/WireHttp.php index 587087de..d68d6271 100644 --- a/wire/core/WireHttp.php +++ b/wire/core/WireHttp.php @@ -666,7 +666,6 @@ class WireHttp extends Wire { $timeout = isset($options['timeout']) ? (float) $options['timeout'] : $this->getTimeout(); $postMethods = array('POST', 'PUT', 'DELETE', 'PATCH'); // methods for CURLOPT_POSTFIELDS $isPost = in_array($method, $postMethods); - $contentType = isset($this->headers['content-type']) ? $this->headers['content-type'] : ''; $proxy = ''; if(!empty($options['proxy'])) { @@ -695,11 +694,20 @@ class WireHttp extends Wire { // not reachable: version blocked before sendCURL call } + if($method === 'POST' && empty($this->headers['expect'])) { + // The 'expect' header that CURL uses waits for server to respond that the POST is okay, + // but many servers don't implement this, or ignore it, so we disable it here. + $this->headers['expect'] = ''; + } + if(count($this->headers)) { - if($isPost && !empty($this->data) && $contentType === self::defaultPostContentType) { + /* kept for temporary reference: + if($isPost && !empty($this->data) && $this->>headers['content-type'] === self::defaultPostContentType) { // CURL does not work w/default POST content-type when sending POST variables array + // if setting array (rather than query string) for CURLOPT_POSTFIELDS $this->headers['content-type'] = 'multipart/form-data; charset=utf-8'; } + */ $headers = array(); foreach($this->headers as $name => $value) { $headers[] = "$name: $value"; @@ -722,7 +730,9 @@ class WireHttp extends Wire { if(!empty($this->data)) { if($isPost) { - curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data); + // setting data as associative array adds a boundary to the content-type header that we don’t + // want so we set value as query string from http_build_query rather than associative array + curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($this->data)); } else { $content = http_build_query($this->data); if(strlen($content)) $url .= (strpos($url, '?') === false ? '?' : '&') . $content; @@ -773,6 +783,12 @@ class WireHttp extends Wire { curl_setopt($curl, $opt, $optVal); } } + + // Enables it to work on URLs that set cookies then redirect + // such as: https://galesupport.com/novelGeo/novelGeoLink.php?loc=nysl_ca_sar&db=AONE + // $tempDir = $this->wire()->files->tempDir(); + // $this->cookiePath = $tempDir->get(); + // curl_setopt($curl, CURLOPT_COOKIEJAR, $this->cookiePath); $result = curl_exec($curl);