This likely wasn't due to adding the source parameter. It was more likely but due to a bug I had in the streaming OAuth implementation. Java's URLEncoder converts spaes to '+' instead of '%20'. This got fixed yesterday.
---Mark http://twitter.com/mccv On Mon, Jun 28, 2010 at 5:08 PM, Matt Harris <thematthar...@twitter.com> wrote: > Wil, > Fantastic. So glad you got it working, and thanks for sharing the solution > which worked for you. > Matt > > On Mon, Jun 28, 2010 at 10:10 AM, Wil <willi...@gmail.com> wrote: >> >> Hi Taylor, >> >> Finally! It now works. TweetSharp includes the source parameter by >> default on all requests (I think). Thus, I overrode the >> TwitterClientInfo just for that request and cleared out the >> "ClientName" field. Now it works! >> >> I guess on your side, the code filters out unknown parameters before >> doing the signature verification thing huh? >> >> Thanks a lot for helping! (though TweetSharp has another problem of >> dropping off the stream connection prematurely... that's another topic >> to discuss after I do more poking) >> >> Regards, >> Wil >> >> On Jun 29, 12:49 am, Taylor Singletary <taylorsinglet...@twitter.com> >> wrote: >> > Hi Wil, >> > >> > Did some more tests. Why are you passing source in this context? I don't >> > recall this being an operator for the Streaming API. If you're passing >> > it as >> > some kind of analogue to a source parameter you'd pass in basic auth on >> > tweet creation, it's unnecessary here unless there's some other use for >> > it >> > that I'm unaware of. Without the source parameter, I'm able to make this >> > call work. >> > >> > Taylor >> > >> > >> > >> > On Mon, Jun 28, 2010 at 9:40 AM, Wil <willi...@gmail.com> wrote: >> > > Hi again, >> > >> > > I made a "real" request this time because in the previous one, I >> > > couldn't control the nonce and timestamp generation directly so I >> > > copy- >> > > pasted the code it used and modified it a bit. This is the "real" >> > > generated data which has a non-mock nonce and timestamp. >> > >> > > Timestamp: "1277742686" >> > > Nonce: "ufywbndxv0qevuh0" >> > >> > > Base String: >> > >> > > POST&http%3A%2F%2Fstream.twitter.com%2F1%2Fstatuses >> > > %2Ffilter.json&follow%3D156934710%26oauth_consumer_key >> > > %3DTwitterConsumerKey%26oauth_nonce >> > > %3Dufywbndxv0qevuh0%26oauth_signature_method%3DHMAC- >> > > SHA1%26oauth_timestamp%3D1277742686%26oauth_token%3DTwitterAccessToken >> > > %26oauth_version%3D1.0%26source%3DWildfire%2520by%2520Implication >> > >> > > Signature: >> > > YRXJUMYs0bRzkDZSTXesGfIWhQ8%3D >> > >> > > Packet Capture: >> > > - Http: Request, POST /1/statuses/filter.json , Using OAuth >> > > Authorization >> > > Command: POST >> > > + URI: /1/statuses/filter.json >> > > ProtocolVersion: HTTP/1.1 >> > > - Authorization: OAuth >> > > + Authorization: OAuth >> > >> > > >> > > oauth_consumer_key="TwitterConsumerKey",oauth_token="TwitterAccessToken",oa >> > > uth_nonce="ufywbndxv0qevuh0",oauth_timestamp="1277742686",oauth_signature_m >> > > ethod="HMAC- >> > > >> > > SHA1",oauth_signature="YRXJUMYs0bRzkDZSTXesGfIWhQ8%3D",oauth_version="1.0", >> > > + ContentType: application/x-www-form-urlencoded >> > > Host: stream.twitter.com >> > > ContentLength: 51 >> > >> > > - Http: HTTP Payload, URL: /1/statuses/filter.json >> > > - payload: HttpContentType = application/x-www-form-urlencoded >> > > source: Wildfire%20by%20Implication >> > > follow: 156934710 >> > >> > > It still looks correct though... >> > >> > > Regards, >> > > Wil >> > >> > > On Jun 29, 12:21 am, Wil <willi...@gmail.com> wrote: >> > > > Hi, >> > >> > > > I got exactly the same values: >> > >> > > > Base string: >> > > > POST&http%3A%2F%2Fstream.twitter.com%2F1%2Fstatuses >> > > > %2Ffilter.json&follow%3D156934710%26oauth_consumer_key >> > > > >> > > > %3DTwitterConsumerKey%26oauth_nonce%3Dabcdefgh%26oauth_signature_method >> > > > %3DHMAC-SHA1%26oauth_timestamp%3D1277739588%26oauth_token >> > > > >> > > > %3DTwitterAccessToken%26oauth_version%3D1.0%26source%3DWildfire%2520by >> > > > %2520Implication >> > >> > > > Signature (escaped): >> > > > rYGiA6H2UXog0nYOzTeUKwJSssM%3D >> > >> > > > Authorization Header: >> > >> > > >> > > oauth_consumer_key="TwitterConsumerKey",oauth_token="TwitterAccessToken",oa >> > > >> > > uth_nonce="abcdefgh",oauth_timestamp="1277739588",oauth_signature_method="H >> > > MAC- >> > > > SHA1",oauth_signature="rYGiA6H2UXog0nYOzTeUKwJSssM >> > > > %3D",oauth_version="1.0" >> > >> > > > Post content: >> > > > source=Wildfire%20by%20Implication&follow=156934710 >> > >> > > > On Jun 28, 11:45 pm, Taylor Singletary >> > > > <taylorsinglet...@twitter.com> >> > > > wrote: >> > >> > > > > Let's start from a common point. By using the same inputs, we can >> > > > > try >> > > and >> > > > > meet in the middle with exactly the same signature, signature base >> > > string, >> > > > > and authorization header. >> > >> > > > > Using the following values: >> > > > > Consumer Key: TwitterConsumerKey >> > > > > Consumer Secret: TwitterConsumerSecret >> > > > > Access Token: TwitterAccessToken >> > > > > Access Token Secret: TwitterAccessTokenScret >> > > > > OAuth Nonce: abcdefgh >> > > > > OAuth Timestamp: 1277739588 >> > >> > > > > URL:http://stream.twitter.com/1/statuses/filter.json >> > >> > > > > POST Body: >> > > > > follow=156934710&source=Wildfire%20by%20Implication >> > >> > > > > Assuming these exact values, the following should be the result: >> > >> > > > > POST body: >> > > > > follow=156934710&source=Wildfire%20by%20Implication >> > >> > > > > Signature Base String: >> > > > > POST&http%3A%2F%2Fstream.twitter.com >> > >> > > >> > > %2F1%2Fstatuses%2Ffilter.json&follow%3D156934710%26oauth_consumer_key%3DTwi >> > > >> > > tterConsumerKey%26oauth_nonce%3Dabcdefgh%26oauth_signature_method%3DHMAC-SH >> > > >> > > A1%26oauth_timestamp%3D1277739588%26oauth_token%3DTwitterAccessToken%26oaut >> > > h_version%3D1.0%26source%3DWildfire%2520by%2520Implication >> > >> > > > > Signing Secret >> > > > > TwitterConsumerSecret&TwitterAccessTokenSecret >> > >> > > > > Signature >> > > > > rYGiA6H2UXog0nYOzTeUKwJSssM= >> > >> > > > > Authorization Header >> > > > > OAuth oauth_nonce="abcdefgh", oauth_signature_method="HMAC-SHA1", >> > > > > oauth_timestamp="1277739588", >> > > > > oauth_consumer_key="TwitterConsumerKey", >> > > > > oauth_token="TwitterAccessToken", >> > > > > oauth_signature="rYGiA6H2UXog0nYOzTeUKwJSssM%3D", >> > > > > oauth_version="1.0" >> > >> > > > > Using these values do you get the same signature and other values? >> > >> > > > > Taylor >> > >> > > > > On Mon, Jun 28, 2010 at 8:21 AM, Wil <willi...@gmail.com> wrote: >> > > > > > Oh wait, it does include them I just missed it. >> > >> > > > > > So much for premature celebration... >> > >> > > > > > On Jun 28, 11:10 pm, Wil <willi...@gmail.com> wrote: >> > > > > > > The thing wasn't including the POST parameters in the signing! >> > > > > > > I >> > > think >> > > > > > > I got it! >> > >> > > > > > > On Jun 28, 10:54 pm, Wil <willi...@gmail.com> wrote: >> > >> > > > > > > > Ah wait, I ran a couple more tests just to be sure and the >> > > signatures >> > > > > > > > match the sent sniffed one.... guess I missed something >> > > previously... >> > >> > > > > > > > Base: >> > > > > > > > POST&http%3A%2F%2Fstream.twitter.com%2F1%2Fstatuses >> > > > > > > > %2Ffilter.json&follow%3D156934710%26oauth_consumer_key >> > > > > > > > %3DrHYIlqotmSfiGc6OfFtw%26oauth_nonce%3Deodjuo8ystdcyl3f >> > > > > > > > %26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp >> > > > > > > > %3D1277736634%26oauth_token%3D156934710- >> > >> > > >> > > J4HkTzZOaHk7ZBnXPzmqopoQS9pm2NjDJmMDEw4E%26oauth_version%3D1.0%26source >> > > > > > > > %3DWildfire%2520by%2520Implication >> > >> > > > > > > > Signature: >> > > > > > > > nt%2F5itdHGoVr8gRloaBOakSmUbM%3D >> > >> > > > > > > > Sent: >> > > > > > > > oauth_consumer_key="rHYIlqotmSfiGc6OfFtw" >> > > > > > > > >> > > > > > > > oauth_token="156934710-J4HkTzZOaHk7ZBnXPzmqopoQS9pm2NjDJmMDEw4E" >> > > > > > > > oauth_nonce="eodjuo8ystdcyl3f" >> > > > > > > > oauth_timestamp="1277736634" >> > > > > > > > oauth_signature_method="HMAC-SHA1" >> > > > > > > > oauth_signature="nt%2F5itdHGoVr8gRloaBOakSmUbM%3D" >> > > > > > > > oauth_version="1.0" >> > >> > > > > > > > On Jun 28, 10:35 pm, Wil <willi...@gmail.com> wrote: >> > >> > > > > > > > > Hi Taylor, >> > >> > > > > > > > > Ok. Here's the entire thing: >> > >> > > > > > > > > Generated base string: >> > > > > > > > > POST&http%3A%2F%2Fstream.twitter.com%2F1%2Fstatuses >> > > > > > > > > %2Ffilter.json&follow%3D156934710%26oauth_consumer_key >> > > > > > > > > %3DrHYIlqotmSfiGc6OfFtw%26oauth_nonce >> > > > > > > > > %3Dmvzi5szav5dciif4%26oauth_signature_method%3DHMAC- >> > > > > > > > > >> > > > > > > > > SHA1%26oauth_timestamp%3D1277735188%26oauth_token%3D156934710- >> > >> > > >> > > J4HkTzZOaHk7ZBnXPzmqopoQS9pm2NjDJmMDEw4E%26oauth_version%3D1.0%26source >> > > > > > > > > %3DWildfire%2520by%2520Implication >> > >> > > > > > > > > calculated signature: %2FgqbnKcwmnpFMGnqNUK3kr6waI0%3D >> > >> > > > > > > > > Sniffed authorization header: >> > > > > > > > > oauth_consumer_key="rHYIlqotmSfiGc6OfFtw" >> > >> > > oauth_token="156934710-J4HkTzZOaHk7ZBnXPzmqopoQS9pm2NjDJmMDEw4E" >> > > > > > > > > oauth_nonce="6qzbdouhrz40dqs4" >> > > > > > > > > oauth_timestamp="1277735291" >> > > > > > > > > oauth_signature_method="HMAC-SHA1" >> > > > > > > > > oauth_signature="2yRkYN7j8YpS0%2FgrFSNKnoCrk7Y%3D" >> > > > > > > > > oauth_version="1.0" >> > >> > > > > > > > > You're right, something seems to be wrong with the >> > > > > > > > > signature. >> > > I'll >> > > > > > > > > continue to investigate this.... >> > >> > > > > > > > > Regards, >> > > > > > > > > Wil >> > > > > > > > > On Jun 28, 10:23 pm, Taylor Singletary < >> > > taylorsinglet...@twitter.com >> > >> > > > > > > > > wrote: >> > >> > > > > > > > > > Wil: Can you retrieve the signature base string (again, >> > > > > > > > > > from >> > > your >> > > > > > current >> > > > > > > > > > work) from your library when attempting the call that >> > > > > > > > > > returns >> > > 401? >> > > > > > There >> > > > > > > > > > must be something minor going amiss there with this >> > > > > > > > > > parameter >> > > for >> > > > > > some >> > > > > > > > > > reason. >> > >> > > > > > > > > > Thanks, >> > > > > > > > > > Taylor >> > >> > > > > > > > > > On Sat, Jun 26, 2010 at 12:08 PM, John Kalucki < >> > > j...@twitter.com> >> > > > > > wrote: >> > > > > > > > > > > An invalid delimited parameter is ignored, and won't >> > > > > > > > > > > cause >> > > a 401. >> > >> > > > > > > > > > > On Sat, Jun 26, 2010 at 2:04 AM, Wil >> > > > > > > > > > > <willi...@gmail.com> >> > > wrote: >> > >> > > > > > > > > > >> Hi, >> > >> > > > > > > > > > >> @John: I removed the delimited=1 parameter and it >> > > > > > > > > > >> still >> > > gave me >> > > > > > 401's. >> > >> > > > > > > > > > >> @Taylor: I checked my system clock and does not >> > > > > > > > > > >> differ >> > > from the >> > > > > > server >> > > > > > > > > > >> time by more than 5 minutes. >> > > > > > > > > > >> The code works with the following which I've used: >> > > > > > > > > > >> 1)OAuthauthentication methods >> > > > > > > > > > >> 2) statuses/user_timeline >> > > > > > > > > > >> 3) 1/favorites/create >> > >> > > > > > > > > > >> (3) is a bit wierd since TweetSharp sends favorite >> > > requests in >> > > > > > this >> > > > > > > > > > >> form: >> > > > > > > > > > >>http://api.twitter.com/1/favorites/create/######.json >> > >> > > > > > > > > > >> and the POST body contains this: >> > > > > > > > > > >> source=Wildfire%20by%20Implication >> > >> > > > > > > > > > >> Yet it still works. I haven't tried other things in >> > > TweetSharp >> > > > > > that >> > > > > > > > > > >> does POST though. >> > > > > > > > > > >> I thought that it was probably the read/write >> > > > > > > > > > >> permissions >> > > that's >> > > > > > > > > > >> causing the problem because I initially set the App >> > > > > > > > > > >> as >> > > read-only >> > > > > > (I >> > > > > > > > > > >> changed it to write-access when I implemented the >> > > favorite). I >> > > > > > then >> > > > > > > > > > >> recreated the client information with read&write >> > > > > > > > > > >> access. >> > > So I >> > > > > > guess >> > > > > > > > > > >> permissions weren't the problem. >> > >> > > > > > > > > > >> I did some packet sniffing to be extra sure that it's >> > > sending >> > > > > > the data >> > > > > > > > > > >> as POST... and I got this: (using Microsoft NetMon >> > > > > > > > > > >> 3.3) >> > > > > > > > > > >> - Http: Request, POST /1/statuses/filter.json , >> > > > > > > > > > >> UsingOAuth >> > > > > > > > > > >> Authorization... >> > >> > read more » > > > > -- > > > Matt Harris > Developer Advocate, Twitter > http://twitter.com/themattharris >