diff --git a/lib/PushTask.php b/lib/PushTask.php index 7ea1f0e..d44c587 100644 --- a/lib/PushTask.php +++ b/lib/PushTask.php @@ -91,6 +91,13 @@ class PushTask { if($content_hash != $feed->content_hash) { $feed->content_hash = $content_hash; + $headers = request\parse_headers($response['headers']); + if(array_key_exists('Content-Type', $headers)) { + $feed->content_type = $headers['Content-Type']; + } + $feed->content = $response['body']; + $feed->save(); + $subscribers = ORM::for_table('subscriptions')->where('feed_id', $feed->id)->where('active', 1)->find_many(); foreach($subscribers as $s) { echo "Queuing notification for feed_id=$feed_id ($feed->feed_url) subscription_id=$s->id ($s->callback_url)\n"; @@ -98,11 +105,10 @@ class PushTask { } } else { + $feed->save(); echo "Feed body has the same content hash as last time, not notifying subscribers\n"; } - $feed->save(); - } else { echo "Feed not found\n"; } @@ -144,7 +150,9 @@ class PushTask { echo "Notifying subscriber!\n"; $subscription->date_last_ping_sent = db\now(); - $response = request\post($subscription->callback_url, []); + $response = request\post($subscription->callback_url, $feed->content, false, [ + 'Content-Type: ' . ($feed->content_type ?: 'text/plain') + ]); $subscription->last_ping_status = $response['status']; $subscription->last_ping_headers = $response['headers']; $subscription->last_ping_body = $response['body']; diff --git a/lib/request.php b/lib/request.php index 109aa3e..1775ec4 100644 --- a/lib/request.php +++ b/lib/request.php @@ -34,17 +34,20 @@ function get_head($url) { ]; } -function post($url, $params, $format='form') { +function post($url, $params, $format='form', $headers=[]) { $ch = curl_init($url); set_user_agent($ch); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if($format == 'json') { $body = json_encode($params); - curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json')); - } else { + $headers[] = 'Content-type: application/json'; + } elseif($format == 'form') { $body = http_build_query($params); + } else { + $body = $params; } + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $body); curl_setopt($ch, CURLOPT_HEADER, true); @@ -57,9 +60,33 @@ function post($url, $params, $format='form') { ]; } +function parse_headers($headers) { + $retVal = array(); + $fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $headers)); + foreach($fields as $field) { + if(preg_match('/([^:]+): (.+)/m', $field, $match)) { + $match[1] = preg_replace_callback('/(?<=^|[\x09\x20\x2D])./', function($m) { + return strtoupper($m[0]); + }, strtolower(trim($match[1]))); + // If there's already a value set for the header name being returned, turn it into an array and add the new value + $match[1] = preg_replace_callback('/(?<=^|[\x09\x20\x2D])./', function($m) { + return strtoupper($m[0]); + }, strtolower(trim($match[1]))); + if(isset($retVal[$match[1]])) { + if(!is_array($retVal[$match[1]])) + $retVal[$match[1]] = array($retVal[$match[1]]); + $retVal[$match[1]][] = $match[2]; + } else { + $retVal[$match[1]] = trim($match[2]); + } + } + } + return $retVal; +} + function set_user_agent(&$ch) { // Unfortunately I've seen a bunch of websites return different content when the user agent is set to something like curl or other server-side libraries, so we have to pretend to be a browser to successfully get the real HTML - curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) p3k/Switchboard/0.1.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36'); + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) p3k/Switchboard/0.1.1 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36'); } function response_is($status, $prefix) {