Problem with update_with_media on php


#1

i got no response with update_with_media. it’s log below

=====post data======
string(100590) "--------------------505ee30e27e2d
Content-Type: application/octet-stream
Content-Disposition: form-data; name=“media[]”; filename=“1.jpg”


--------------------505ee30e27e2d
content-disposition: form-data; name=“oauth_consumer_key”

xxxxx
--------------------505ee30e27e2d
content-disposition: form-data; name=“oauth_nonce”

59043e6498e81f629b7140688013fd7e
--------------------505ee30e27e2d
content-disposition: form-data; name=“oauth_signature”

LG+a0nF15eNZi+3zqYacpqB+xSc=
--------------------505ee30e27e2d
content-disposition: form-data; name=“oauth_signature_method”

HMAC-SHA1
--------------------505ee30e27e2d
content-disposition: form-data; name=“oauth_timestamp”

1348395790
--------------------505ee30e27e2d
content-disposition: form-data; name=“oauth_token”

xxxxxx
--------------------505ee30e27e2d
content-disposition: form-data; name=“oauth_version”

1.0
--------------------505ee30e27e2d
content-disposition: form-data; name=“status”

xxx
--------------------505ee30e27e2d–"
=====info=====
Array
(
[url] => https://api.twitter.com/1.1/statuses/update_with_media.json
[content_type] =>
[http_code] => 400
[header_size] => 154
[request_size] => 326
[filetime] => -1
[ssl_verify_result] => 20
[redirect_count] => 0
[total_time] => 8.517
[namelookup_time] => 0
[connect_time] => 0
[pretransfer_time] => 1.045
[size_upload] => 100590
[size_download] => 0
[speed_download] => 0
[speed_upload] => 11810
[download_content_length] => 0
[upload_content_length] => 100590
[starttransfer_time] => 3.042
[redirect_time] => 0
[certinfo] => Array
(
)

[primary_ip] => 127.0.0.1
[primary_port] => 8087
[local_ip] => 127.0.0.1
[local_port] => 36953
[redirect_url] => 
[request_header] => POST /1.1/statuses/update_with_media.json HTTP/1.1

User-Agent: xxx Bot
Host: api.twitter.com
Accept: /
Content-Length: 100590
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

)
=====$response=====
NULL


#2

What library are you using for this? You’ll find, especially with this method, it much much easier to use header-based OAuth rather than using them as POST paramaters. It also appears like you might be sending multiple Content-Type headers. Are you handling the special OAuth case for when you’re performing a POST that is not x-www-form-urlencoded?


#3

here is my php code

<?php class twitter { public $consumer_key; public $consumer_secret; public $access_token; public $access_token_secret; public $http_code; public $http_info; public $host = 'https://api.twitter.com/1.1/'; public $postdata; public $timeout = 30; public $connecttimeout = 30; public $ssl_verifypeer = FALSE; public $format = 'json'; public $decode_json = TRUE; public $useragent = 'Mars Bot'; public $debug = FALSE; public static $version = '1.0'; public static $SignatureMethod = 'HMAC-SHA1'; public static $boundary = ''; private $parameters; private $http_method; private $http_url; private $http_header; private $proxyinuse = FALSE; private $proxyandport; private $userandpass; public function init($consumer_key, $consumer_secret, $access_token, $access_token_secret, $proxyinuse = FALSE, $proxyandport = '', $userandpass = '', $debug = false){ $this->consumer_key = $consumer_key; $this->consumer_secret = $consumer_secret; $this->access_token = $access_token; $this->access_token_secret = $access_token_secret; $this->proxyinuse = $proxyinuse; $this->proxyandport = $proxyandport; $this->userandpass = $userandpass; $this->debug = $debug; } private static function generate_nonce(){ $mt = microtime(); $rand = mt_rand(); return md5($mt . $rand); } private static function generate_timestamp(){ return time(); } public function get_normalized_http_url(){ $parts = parse_url($this->http_url); $port = @$parts['port']; $scheme = $parts['scheme']; $host = $parts['host']; $path = @$parts['path']; $port or $port = ($scheme == 'https') ? '443' : '80'; if (($scheme == 'https' && $port != '443') || ($scheme == 'http' && $port != '80')) { $host = "$host:$port"; } return "$scheme://$host$path"; } public function get_normalized_http_method(){ return strtoupper($this->http_method); } public function get_signature_base_string() { $parts = array( $this->get_normalized_http_method(), $this->get_normalized_http_url(), $this->get_signable_parameters() ); $parts = self::urlencode_rfc3986($parts); return implode('&', $parts); } public function get_signable_parameters() { $params = $this->parameters; if(isset($params['media[]'])){ unset($params['media[]']); } if (isset($params['oauth_signature'])){ unset($params['oauth_signature']); } return self::build_http_query($params); } public static function urlencode_rfc3986($input){ if(is_array($input)){ return array_map(array('self', 'urlencode_rfc3986'), $input); }elseif(is_scalar($input)){ return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($input))); }else{ return ''; } } public function set_parameter($name, $value, $allow_duplicates = true){ if ($allow_duplicates && isset($this->parameters[$name])){ if (is_scalar($this->parameters[$name])){ $this->parameters[$name] = array($this->parameters[$name]); } $this->parameters[$name][] = $value; }else{ $this->parameters[$name] = $value; } } public function set_base_data($http_method, $http_url, $parameters=NULL) { @$parameters or $parameters = array(); $defaults = array( 'oauth_version' => self::$version, 'oauth_token' => $this->access_token, 'oauth_timestamp' => self::generate_timestamp(), 'oauth_nonce' => self::generate_nonce(), 'oauth_consumer_key' => $this->consumer_key, ); $parameters = array_merge($defaults, $parameters); $this->parameters = $parameters; $this->http_method = $http_method; $this->http_url = $http_url; } public function build_signature() { $base_string = $this->get_signature_base_string(); $key_parts = array($this->consumer_secret, $this->access_token_secret); $key_parts = self::urlencode_rfc3986($key_parts); $key = implode('&', $key_parts); return base64_encode(hash_hmac('sha1', $base_string, $key, true)); } public function set_sign_request_data() { $this->set_parameter('oauth_signature_method', self::$SignatureMethod, false); $signature = $this->build_signature(); $this->set_parameter('oauth_signature', $signature, false); } public function to_postdata( $multi = false ){ if($multi) return self::build_http_query_multi($this->parameters); else return self::build_http_query($this->parameters); } public function to_header($realm=null) { $first = true; if($realm) { $out = 'Authorization: OAuth realm="' . self::urlencode_rfc3986($realm) . '"'; $first = false; } else $out = 'Authorization: OAuth'; $total = array(); foreach ($this->parameters as $k => $v) { if (substr($k, 0, 5) != "oauth") continue; if (is_array($v)) { throw new Exception('Arrays not supported in headers'); } $out .= ($first) ? ' ' : ','; $out .= self::urlencode_rfc3986($k) . '="' . self::urlencode_rfc3986($v) . '"'; $first = false; } return $out; } public function to_url(){ $post_data = $this->to_postdata(); $out = $this->get_normalized_http_url(); if($post_data){ $out .= '?'.$post_data; } return $out; } public function oAuthRequest($url, $method, $parameters, $multi=false) { if (strrpos($url, 'http://') !== 0 && strrpos($url, 'http://') !== 0){ $url = "{$this->host}{$url}.{$this->format}"; } $this->set_base_data($method, $url, $parameters); $this->set_sign_request_data(); switch ($method){ case 'GET': return $this->http($this->to_url(), 'GET'); default: return $this->http($this->get_normalized_http_url(), $method, $this->to_postdata($multi)); } } function http($url, $method, $postfields=null, $multi=false, $headermulti = "") { $this->http_info = array(); $ci = curl_init(); curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent); curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout); curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($ci, CURLOPT_RETURNTRANSFER, true); curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer); curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader')); curl_setopt($ci, CURLOPT_HEADER, false); if($this->proxyinuse){ if($this->proxyandport){ curl_setopt($ci, CURLOPT_HTTPPROXYTUNNEL, 1); curl_setopt($ci, CURLOPT_PROXY, $this->proxyandport); } if($this->userandpass){ curl_setopt($ci, CURLOPT_PROXYUSERPWD, $this->userandpass); } } switch ($method) { case 'POST': curl_setopt($ci, CURLOPT_POST, true); if (!empty($postfields)) { curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields); } break; case 'DELETE': curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE'); if (!empty($postfields)) { $url = "{$url}?{$postfields}"; } default: break; } $header_array=array(); if($multi) $header_array = array("Content-Type: multipart/form-data; boundary=" . self::$boundary , "Expect: "); array_push($header_array,$headermulti); curl_setopt($ci, CURLOPT_HTTPHEADER, $header_array); curl_setopt($ci, CURLINFO_HEADER_OUT, true); curl_setopt($ci, CURLOPT_URL, $url); $response = curl_exec($ci); $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); $this->http_info = array_merge($this->http_info, curl_getinfo($ci)); $this->url = $url; if ($this->debug) { echo "=====post data======\r\n"; var_dump($postfields); echo '=====info====='."\r\n"; print_r( curl_getinfo($ci) ); echo '=====$response====='."\r\n"; print_r( $response ); } curl_close ($ci); return $response; } public static function build_http_query($params){ if (!$params) return ''; $keys = self::urlencode_rfc3986(array_keys($params)); $values = self::urlencode_rfc3986(array_values($params)); $params = array_combine($keys, $values); uksort($params, 'strcmp'); $pairs = array(); foreach ($params as $parameter => $value){ if (is_array($value)){ natsort($value); foreach ($value as $duplicate_value){ $pairs[] = $parameter . '=' . $duplicate_value; } }else{ $pairs[] = $parameter . '=' . $value; } } return implode('&', $pairs); } public static function build_http_query_multi($params) { if (!$params) return ''; uksort($params, 'strcmp'); $pairs = array(); self::$boundary = $boundary = uniqid('------------------'); $MPboundary = '--'.$boundary; $endMPboundary = $MPboundary. '--'; $multipartbody = ''; foreach ($params as $parameter => $value) { if( in_array($parameter, array('media[]')) && $value{0} == '@' ) { $url = ltrim( $value, '@' ); $content = file_get_contents( $url ); $array = explode( '?', basename( $url ) ); $filename = $array[0]; $multipartbody .= $MPboundary . "\r\n"; $multipartbody .= 'Content-Disposition: form-data; name="' . $parameter . '"; filename="' . $filename . '"'. "\r\n"; $multipartbody .= 'Content-Type: application/octet-stream' ."\r\n\r\n"; $multipartbody .= $content. "\r\n"; } else { $multipartbody .= $MPboundary . "\r\n"; $multipartbody .= 'content-disposition: form-data; name="' . $parameter . "\"\r\n\r\n"; $multipartbody .= $value."\r\n"; } } $multipartbody .= $endMPboundary; return $multipartbody; } function getHeader($ch, $header){ $i = strpos($header, ':'); if (!empty($i)) { $key = str_replace('-', '_', strtolower(substr($header, 0, $i))); $value = trim(substr($header, $i + 2)); $this->http_header[$key] = $value; } return strlen($header); } function post($url, $parameters=array(), $multi = false){ $response = $this->oAuthRequest($url, 'POST', $parameters , $multi); if ($this->format === 'json' && $this->decode_json) { return json_decode($response, true); } return $response; } function add($text) { $param = array(); $param['status'] = $text; return $this->post('statuses/update', $param); } public function addpic($status, $pic_path, $lat = NULL, $long = NULL) { $params = array(); $params['status'] = $status; $params['media[]'] = '@'.$pic_path; if ($lat) { $params['lat'] = floatval($lat); } if ($long) { $params['long'] = floatval($long); } return $this->post('statuses/update_with_media', $params, true); } } $c = new twitter(); $c->init($consumer_key, $consumer_secret, $access_token, $access_token_secret, $proxyinuse, $proxyandport, $userandpass); $c->addpic('xxxxx', 'E:\\1.jpg'); btw, $c-add('xxxxx') works well

#4

Your code seems to just drop media[] and oauth_signature when they are parameters from the signature base string rather than pivoting on the content type and ignoring all non oauth-* parameters when that’s the case. It also looks like you’re sending oauth_* parameters as POST parameters when you should prepare it in an authorization header instead.


#5

I to discuss to clarify my profile setting account https:// @ twifter.com imeldabcastro username, link my account Google Developer,Properties Favorite Toolbar Net Frameworks ,Full Title Name Certification Path, FAQ CENTER, URL instead new Browse Custom Immigration Services,connection wizard Microsoft D.C. Technologies,published 1598, Timeline Window 2000.Timezone Bit 64 ,Format Region, Location ,Map World Clock, Eastern Standard Timezone Format 12:00 am, 12:pm, 24th hours in one day, Format YYY/MM/d. Timeline Century, Millenium,
Quarter, higher year generation ,Google Earth, Technologies, Safe Harbor Frameworks,Government
Office ,Zip Code N.Y. 10001,United Kingdom, History of Apple Purple Color World Cup, U.S. Navy,
Shipping Lines. Favorite Software ,Smart Mobile Wireless PIN, i.d. passport account Imelda Castro
Camagong, is my personalized configure ,multiple information Google Developer,Favorite Menu Bar.
installer ,self regulatory ,from Google Chrome Content, Wikipedia, enter Free Encyclopedia, Upgrade Expedia,Trustee Blog Map, Versign,Full Title Name Certification Path, Router From Header to Footer, Height 8’5 distance parameter 58ft. Sized,240 X 480, width 13’th 13th’ image
jpeg,library system folder, picture ,indiividual plant,history of multiplied Peter,Moses,Adam,Stories of Favorite Bookmark, Nature
life of a tree ,apple fruitfull life, virgin heart ,God Life as an Angel. Glory to God, Graces of Love.started Index Glossary, A-Z, Language English ads on tagalog,Site: https://Google,Facebook
share Twifter linked in Microsoft XP Professional, Live Window, Outlook.
Microsoft Internet Explorer,Window 2000 ,Millineum Digital Data, Google Filter ,Properties Favorite
Menu ,Toolbar Net Frameworks,Microsoft D,C. Technologies ,published 1598,Trademarks and Contribute 1598, Mozilla Websites, Legal Licensing,Policies, Privacy & Rights,Terms and Condition. Copyright ,Timeline 2000 Millenium Year, Silver Color. , From Apple Purple Color,
World Cup,History Event, Arch of Noah.Hundred Years Century.7 color Rainbow,is a sign of Ptomises Everlasting Life,Body of Christ, Written from the stars.jpg image,link my information
Yahoo Messenger mobile ,contact email address imeldacamagong@yahoo.com, bit 64 ,Nickname
Milley ,invisible to everyone but always available to everyone,sending messages.
Eastern Standard Time,County Region Format,Nationwide.Day & Night.,Update.Microsoft Worldwide.advance setting, Skype One Drive, Window 8, original color ,blue sky,white clouds, Enlighten Day & Night, Microsoft Worldwide.,Microsoft XP PRO 8.1 RT.8.1 ,Help & Support ,FAQ CENTER.


#6

Thank You ,for text message on my Iphone mobile +639283963025, link Code, number Twifter Page,
& Facebook Page ,Security Code,848772/ updated date August 24, 2014, Timezone Format,11:36 am ,arrived.Contact Phone information ,Imelda Camagong., automatically access,after sending
Twifer Code, in connection of my facebook code,after i click, my contact mobile smartphone number,
information , Smart Filter Screen. Picture ,Photo to notified my personalized ,configured profiled contact account Imelda Camagong, identified with my picture photo ,ME ,Milley, Female ,and @twifter/imeldabcastro ,one with multiple account ,discrepancy, legal document,marriage certification ,authenticated registered National Statistic Office, Republc of the Philippines… ,


#7

Function Post, request format , Code return json,response true./ return json decode response,true.