読者です 読者をやめる 読者になる 読者になる

nsIWebBrowserPersist の saveURI で POST する方法

よくわからなくてちょっとはまったので、メモるよ。

let download = function (url, filepath, referer, postDataText) {
  let dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
  let wbp = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Ci.nsIWebBrowserPersist);

  // リファラ
  let refererURI = Cc['@mozilla.org/network/standard-url;1'].createInstance(Ci.nsIURI);
  refererURI.spec = referer;

  // キャッシュ
  let cache = null;
  try {
    let sh = getWebNavigation().sessionHistory;
    cache = sh.getEntryAtIndex(sh.index, false).QueryInterface(Ci.nsISHEntry).postData;
  } catch (e) { /* DO NOTHING */ }

  // 保存先
  let localfile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
  localfile.initWithPath(filepath);
  let file = makeFileURI(localfile);

  // ダウンロードマネージャに登録
  let dl = dm.addDownload(0, makeURL(url, null, null), file, 'Title', null, null, null, null, wbp);
  wbp.progressListener = dl;
  wbp.persistFlags = wbp.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;

  // POST 用のデータ構築
  let postStream = Cc["@mozilla.org/io/string-input-stream;1"]
                    .createInstance(Ci.nsIStringInputStream);
  postStream.setData(postDataText, postDataText.length);

  let  postData = Cc["@mozilla.org/network/mime-input-stream;1"].createInstance(Ci.nsIMIMEInputStream);
  postData.addHeader("Accept-Charset", "utf-8");
  postData.addHeader("Content-Type", "application/x-www-form-urlencoded");
  postData.addContentLength = true;
  postData.setData(postStream);

  // ダウンロード開始!
  wbp.saveURI(makeURL(url), cache, refererURI, postData, null, file);
};

//        POST先URL               保存先                  リファラ               POST内容
download('http://example.com/api', '/tmp/post-test.html', 'http://example.net/', 'anekos_eq_id:nokturnalmortum');

例のPOST先は特に意味がないので、テストする場合は適当に変えてください。