/** * HTTP POST a URL with query parameters, using x-www-form-urlencoded * Content-Type. When redirecting, post data will also be re-posted (watch * potential security implication of this). * * @param $url string URL with or without some query parameters * @param $params array post data in name/value pairs * @param $options array associative array of extra options to pass in. can include: * max_redir int how many levels of redirection to attempt (def 1) * conn_timeout int number of seconds waiting for a connection (def 3) * timeout int total number of seconds to wait, should be * strictly bigger than $conn_timeout (def 12) * block_internal bool security check - prevent retrieving internal facebook urls (def true) * internal_whitelist array whitelist these internal domains (def empty) * close_conns bool whether to shut down all our db connections * before making the request (def true) */ function http_post($url, $params, $options = array()) { global $APP_MAX_REDIRECTS, $APP_RETRY_CONNECT, $APP_CONNECT_TIMEOUT, $APP_CURL_TIMEOUT; $default_options = array('max_redir' => $APP_MAX_REDIRECTS, 'conn_retry' => $APP_RETRY_CONNECT, 'conn_timeout' => $APP_CONNECT_TIMEOUT, 'timeout' => $APP_CURL_TIMEOUT, 'post_tuples' => null); // $options + $default_options results in an assoc array with overlaps // deferring to the value in $options extract($options + $default_options); $curl = curl_init(); if ($max_redir < 1) { $max_redir = 1; } $curl_opts = array(CURLOPT_URL => $url, CURLOPT_CONNECTTIMEOUT => $conn_timeout, CURLOPT_TIMEOUT => $timeout, CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'], CURLOPT_RETURNTRANSFER => 1, CURLOPT_ENCODING => 'gzip', CURLOPT_HTTPHEADER => array('Expect:')); curl_setopt_array($curl, $curl_opts); $last_url = $url; $redirects = 0; $retries = 0; $post_str = http_build_query($params); if (isset($options['post_tuples']) && $options['post_tuples']) { if ($post_str) { $post_str .= '&'; } $assts = array(); foreach ($options['post_tuples'] as $param_val) { list($param, $val) = $param_val; $assts[] = urlencode($param) . '=' . urlencode($val); } $post_str .= implode('&', $assts); } if (isset($params['fb_sig_api_key'])) { $app_id = application_get_id_from_key($params['fb_sig_api_key']); } else { $app_id = null; } if ($max_redir == 1) { curl_setopt($curl, CURLOPT_POSTFIELDS, $post_str); $response = curl_exec($curl); } else { $start_time = microtime(true); for ($attempt = 0; $attempt < $max_redir; $attempt++) { curl_setopt($curl, CURLOPT_HEADER, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_str); $orig_response = curl_exec($curl); // Remove any HTTP 100 headers $response = preg_replace('/HTTP\\/1\\.[01] 100.*\\r\\n(.+\\r\\n)*\\r\\n/', '', $orig_response); if (preg_match('/^HTTP\\/1\\.. 30[127].*\\nLocation: ([^\\r\\n]+)\\r\\n/s', $response, $matches)) { $new_url = $matches[1]; // if $new_url is relative path, prefix with domain name if (!preg_match('/^http(|s):\\/\\//', $new_url) && preg_match('/^(http(?:|s):\\/\\/.*?)\\/|$/', $url, $matches)) { $new_url = $matches[1] . '/' . $new_url; } $last_url = $new_url; curl_setopt($curl, CURLOPT_URL, $new_url); // reduce the timeout, but keep it at least 1 or we wind up with an infinite timeout curl_setopt($curl, CURLOPT_TIMEOUT, max($start_time + $timeout - microtime(true), 1)); ++$redirects; } else { if ($conn_retry && strlen($orig_response) == 0) { // probably a connection failure...if we have time, try again... $time_left = $start_time + $timeout - microtime(true); if ($time_left < 1) { break; } // ok, we've got some time, let's retry curl_setopt($curl, CURLOPT_URL, $last_url); curl_setopt($curl, CURLOPT_TIMEOUT, $time_left); ++$retries; } else { break; // we have a good response here } } } // NOTE: quicker to use strpos for headers, do not compile a RE if (false !== ($pos = strpos($response, "\r\n\r\n"))) { $response = substr($response, $pos + 4); } } $curl_info = curl_getinfo($curl); if ($curl_info['http_code'] == 301 || $curl_info['http_code'] == 302 || $curl_info['http_code'] == 307) { throw new HTTPTooManyRedirsException($url); } if ($curl_info['http_code'] >= 400) { throw new HTTPErrorException($url, $curl_info['http_code'], $response); } if (strlen($response) == 0) { if ($curl_info['http_code']) { throw new HTTPNoDataException($url, $curl_info['http_code']); } else { throw new HTTPNoResponseException($url); } } curl_close($curl); // take into account http hosts that don't use utf-8 if (!empty($curl_info['content_type']) && preg_match('#charset=([^;]+)#i', $curl_info['content_type'], $matches)) { $encoding = strtoupper($matches[1]); if ($encoding != 'UTF-8') { $response = iconv($encoding, 'UTF-8', $response); } } return $response; }
public function application_getPublicInfo($application_id, $application_api_key, $application_canvas_name) { $param_ec = api10_FacebookApiErrorCode::API_EC_PARAM; $param_msg = 'Exactly one of application_id, api_key, or canvas_name is required.'; // parameter checking if ($application_api_key) { if ($application_id || $application_canvas_name) { throw new api10_FacebookApiException(array('error_code' => $param_ec, 'error_msg' => $param_msg)); } $app_id = application_get_id_from_key($application_api_key); } else { if ($application_canvas_name) { if ($application_id) { throw new api10_FacebookApiException(array('error_code' => $param_ec, 'error_msg' => $param_msg)); } $app_id = application_get_fbframe_id($application_canvas_name); } else { if ($application_id) { $app_id = $application_id; } else { throw new api10_FacebookApiException(array('error_code' => $param_ec, 'error_msg' => $param_msg)); } } } if (!$app_id) { $this->throw_code(api10_FacebookApiErrorCode::API_EC_NO_SUCH_APP); } // get the info first, as it allows us to do the rest of this efficiently $app_info = application_get_info($app_id); if (!$app_info) { $this->throw_code(api10_FacebookApiErrorCode::API_EC_NO_SUCH_APP); } $result = new api10_app_info(); $result->app_id = $app_info['application_id']; $result->api_key = $app_info['apikey']; $result->canvas_name = application_get_fbframe_name($app_id); $result->display_name = application_get_name($app_id, $app_info); $result->icon_url = application_get_icon_url($app_id, $app_info); $result->logo_url = application_get_logo_url($app_id, $app_info); $result->description = $app_info['description']; $result->developers = array(); $result->company_name = ''; // figure out whether to return the developers or company name $company_name = $app_info['company_name']; $result->company_name = $company_name; $dev_ids = application_get_owners($app_id); foreach ($dev_ids as $dev_id) { $developer_info = new api10_developer_info(); $developer_info->uid = $dev_id; $developer_info->name = user_get_name($dev_id); $result->developers[] = $developer_info; } return $result; }
// FBOPEN:NOTE : html/canvas.php is a simple demonstration of canvas-like // : functionality, and will vary widely on your system. // : You can try this demo by putting this under your document root and // : sending a request to: // : yourapp.demo/canvas.php?fb_app_name=AAAA&fb_user_id=UUUU&fb_url_suffix=SSSSS // : where AAAA is your app's "display" name (apps.facebook.com/AAAA), // : UUUU is the 'logged in' user id, // : and fb_url_suffix is a URL-encoded string of the parameters // : you wish to send to your callback URL. $rel_canvas_url = $_SERVER['REQUEST_URI']; $url_suffix = urldecode($get_fb_url_suffix); if ($get_fb_app_name) { $app_id = application_get_fbframe_id($get_fb_app_name); } else { if ($get_fb_api_key) { $app_id = application_get_id_from_key($get_fb_api_key); } else { print 'No app corresponding to app name or api key parameters'; error_log('No app corresponding to app name or api key parameters'); exit; } } print_canvas_javascript_references(); if (!($user = $get_fb_user_id)) { print 'No user id parameter'; error_log('No user id parameter'); exit; } $canvas_url = redirect_str($rel_canvas_url, 'www', $ssl = 0, $force_prod = false, $force_protocol = true); print "Facebook Open Platform: Output of Canvas url: {$canvas_url}<hr>"; // no app_id found so assume bad link