LivedoorBlogにAtomPub経由で投稿するのにHttpWebRequestを使うとエラー417 Expectation Failedが返ってきて例外飛ばされる

最近、AtomPubのクライアントの実装をC#でちまちま書いてるんだが、こいつをテストしてて、Hatena Blogだとなんとも無いのに、Livedoor Blogだと、417 Expectation Failedの例外を投げられて、頭抱え込んだのでメモ。

なんてことは無い、答えは、

アフェリエイトで主夫がマネタイズ始めましたlivedoor blogで417 Expectation Failed

初学者の箸置WebRequestのExpectにデフォルトで100-continueがつく件

マジックナンバーHttpClientの417 Expectation Failed

MSDNのServicePoint.Expect100Continueプロパティ

この動きって知らなかった。

HTTPリクエストでは、POSTの場合、ヘッダーとボディの両方をいきなり送りつけるのではなくて、

  1. クライアントは、ヘッダーだけ送る。この際、Expect: 100-continueをヘッダーに足しておく。
  2. サーバーは、OKなら100系、ダメなら4XX系を返す。
  3. クライアントは、100の場合は、ボディを送信する。

とすることで、いきなりボディの大量データを送る前に、拒否されるのかどうかを検証でき、無駄な通信量を減らすことができる。

例えば、クライアントが認証付きでリクエストする際、いきなりヘッダーとボディを送るのではなく、まず認証の情報とExpect: 100-continueが入ったヘッダーを投げて、100 (Continue)が来たらボディを送る、401 (Unauthorized)ならボディを送らない。とすればよい。

で、で、

.NET FrameworkのHttpWebRequestクラスはPOSTに関してデフォルトでこの機能がONになっている。

が、この機能を受け付けないサーバーが世の中には存在する。この機能を受け付けないサーバーは、一般的には、417 Expectation Failedが返ってくる。中にはだんまり決め込むサーバーもあるらしい。

ぐぐってみると、LivedoorBlogのAtomPubだったり、TwitterAPIだったりが417を返すとか。。。

んじゃ、HttpWebRequestのこの機能をOFFにしなくちゃならないのだが、

httpWebRequest.Expect = null; // or = “”; or = “ “;

とか、ましてや、

httpWebRequest.Headers[“Expect”] = null;

では消えてくれない。

正解は、

httpWebRequest.ServicePoint.Expect100Continue = false;

ということで。。。

System.Net.Http.HttpClientを使っている場合は、System.Net.Http.HttpRequestMessageのHeaders.ExpectContinueプロパティをfalseにするか、httpClient.DefaultRequestHeaders.ExpectContinue = falseとする。

いろいろ知らんかった。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください