2

ClojureでSnowplow用のイベント コレクターを構築しています(Ring/Compojure を使用)。Ring で透明なピクセルを提供する際に問題が発生しています。これは、ピクセルを送信するための私のコードです:

(ns snowplow.clojure-collector.responses
  (:import (org.apache.commons.codec.binary Base64)
           (java.io ByteArrayInputStream)))

(def pixel-bytes (Base64/decodeBase64 (.getBytes "R0lGODlhAQABAPAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==")))
(def pixel (ByteArrayInputStream. pixel-bytes))

(defn send-pixel
   []
    {:status  200
     :headers {"Content-Type"   "image/gif"}
     :body    pixel})

サーバーを起動すると、最初に のパスにヒットしたときにsend-pixel、ピクセルがブラウザに正常に配信されます。しかし、2 回目以降は毎回、Ring は本文を送信しません (そして content-length 0)。サーバーを再起動しても同じパターンです。

そうではないいくつかのこと:

  1. を使用してこれを複製しwget、断続性がブラウザのキャッシュの問題ではないことを確認しました
  2. "R01GOD..."コマンドライン ( ) で base64 文字列を生成したcat original.gif | base64ので、そこに問題がないことがわかります
  3. ピクセルが正常に送信されたら、その内容が正しいことを確認しました ( diff original.gif received-pixel.gif)

私は Clojure を初めて使用します。コードに厄介な動的グレムリンがあると思いますが、それを見つけるのに助けが必要です。

4

2 に答える 2

6

投稿した直後にREPLの問題を見つけました:

user=> (import (org.apache.commons.codec.binary Base64) (java.io ByteArrayInputStream))
java.io.ByteArrayInputStream
user=> (def pixel-bytes (Base64/decodeBase64 (.getBytes "R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==")))
#'user/pixel-bytes
user=> (def pixel (ByteArrayInputStream. pixel-bytes))
#'user/pixel
user=> (slurp pixel-bytes)
"GIF89a!�\n,L;"
user=> (slurp pixel-bytes)
"GIF89a!�\n,L;"
user=> (slurp pixel)
"GIF89a!�\n,L;"
user=> (slurp pixel)
""

したがって、基本的に問題はByteArrayInputStream、最初の呼び出しの後に が空になることでした。ミュータブルなデータ構造!

ByteArrayInputStream次のように、応答ごとに新しいものを生成することでバグを修正しました。

    :body    (ByteArrayInputStream. pixel-bytes)}))
于 2012-10-30T14:17:21.557 に答える