C#ではてなブックマークのポストができなくて参ってる
まさかこんな所で詰まるとは思ってなかった。C#でWSSE認証クライアントで見たGET用のソースを元に、はてなブックマークに投稿するコードを組んでみたんですが、ステータスコード 417を返しやがりました。417 Expectation Failedってなんだよぉ・・・
ブログを見てくださっている方で、C#に詳しい方がいらっしゃるならば、どこが間違っているか教えていただけないでしょうか。
以下がエラー吐くコードです。
using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Security.Cryptography; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string username = "user" ; string password = "pass"; string postURI = "http://b.hatena.ne.jp/atom/post"; string uri = "http://d.hatena.ne.jp/tomity/20080213/1202883980"; string comment = "comment"; string entry = "<entry xmlns=\"http://purl.org/atom/ns#\">" + "<title>dummy</title>" + "<link rel=\"related\" type=\"text/html\" href=\"" + uri + " \" />" + "<summary type=\"text/plain\">" + comment + "</summary>" + "</entry>"; byte[] data = Encoding.ASCII.GetBytes(entry); // nonce(HTTPリクエスト毎に生成したセキュリティ・トークン)の作成 <- ランダムな文字 byte[] nonceB = new byte[8]; new Random().NextBytes(nonceB); // Created(Nonceが作成された日時をISO-8601表記で記述したもの) string created = DateTime.Now.ToString("u").Replace(' ', 'T'); byte[] createdB = Encoding.UTF8.GetBytes(created); // PasswordDigest(Nonce, Created, パスワードを文字列連結し // SHA1アルゴリズムでダイジェスト化して生成された文字列を、 // Base64エンコードした文字列) byte[] passwordB = Encoding.UTF8.GetBytes(password); SHA1Managed sha1 = new SHA1Managed(); sha1.Initialize(); byte[] v = new byte[nonceB.Length + createdB.Length + passwordB.Length]; Array.Copy(nonceB, 0, v, 0, nonceB.Length); Array.Copy(createdB, 0, v, nonceB.Length, createdB.Length); Array.Copy(passwordB, 0, v, nonceB.Length + createdB.Length, passwordB.Length); byte[] digest = sha1.ComputeHash(v); // WSSE認証用のヘッダを作成 string format = "UsernameToken Username=\"{0}\", PasswordDigest=\"{1}\", Nonce=\"{2}\", Created=\"{3}\""; string wsseHeader = string.Format(format, username, Convert.ToBase64String(digest), Convert.ToBase64String(nonceB), created); // リクエストの送信と結果の取得 string res = string.Empty; System.Net.HttpWebRequest webreq = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(postURI); webreq.Method = "POST"; webreq.Headers.Add("Authorization", "WSSE profile=\"UsernameToken\""); webreq.Headers.Add("X-WSSE", wsseHeader); webreq.Accept = "application/x.atom+xml, application/xml, text/xml, */*"; webreq.ContentType = "application/x.atom+xml, application/xml, text/xml, */*"; webreq.ContentLength = data.Length; //2008/02/15追記 ServicePoint currentServicePoint = webreq.ServicePoint; if (currentServicePoint == null) { WebProxy proxy = WebProxy.GetDefaultProxy(); currentServicePoint = ServicePointManager.FindServicePoint(postURI, proxy); } currentServicePoint.Expect100Continue = false; //追記分ここまで Stream reqStream = webreq.GetRequestStream(); reqStream.Write(data, 0, data.Length); reqStream.Close(); System.Net.HttpWebResponse webres = (System.Net.HttpWebResponse)webreq.GetResponse(); System.IO.Stream st = webres.GetResponseStream(); System.IO.StreamReader sr = new System.IO.StreamReader(st); res = sr.ReadToEnd(); sr.Close(); st.Close(); } } }
追記
http://q.hatena.ne.jp/1202997886 で回答を募集しています。正しければはてなポイント500ポイントを進呈します。