如何启用drakma来处理URL中的非latin-1字符

时间:2013-06-02 13:58:32

标签: common-lisp drakma

我遇到了一个错误,这个错误是由使用sbcl的给定网址中使用的非Latin-1字符引起的,例如:

(drakma:http-request "http://www.youtube.com/„weird-url")

debugger invoked on a FLEXI-STREAMS:EXTERNAL-FORMAT-ENCODING-ERROR in thread
#<THREAD "initial thread" RUNNING {1002998D23}>:
  #\DOUBLE_LOW-9_QUOTATION_MARK (code 8222) is not a LATIN-1 character.

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(FLEXI-STREAMS::SIGNAL-ENCODING-ERROR
 #<FLEXI-STREAMS::FLEXI-LATIN-1-FORMAT (:ISO-8859-1 :EOL-STYLE :LF)
   {1002F196E3}>
 "~S (code ~A) is not a LATIN-1 character."
 #\DOUBLE_LOW-9_QUOTATION_MARK
 8222)

显然Headers被定义为由RFC2616在Latin-1中发送(这是我在遇到此错误后在github上打开的票证),因此URL必须在传递给drakma之前进行正确编码。但我不知道怎么做,因为显然这是不可能的(因为它不是LATIN-1字符)?

我的例子的工作电话是什么(除了URL是伪造的还可以缩短为http://www.youtube.com)?

(drakma:http-request (magic-encoding-function "http://www.youtube.com/„weird-url"))

2 个答案:

答案 0 :(得分:2)

此问题与DRAKMA无关。这是PURI的错。我使用PURI的叉子:https://github.com/archimag/puri-unicode

答案 1 :(得分:2)

只是想通了,如果缺陷存在于新实例化对象的后处理中,那么解决方法可能是将流程拆分为两部分:

  1. 构造仅包含Latin-1部分的URI。
  2. 设置路径
  3. 就像是:

    (let ((uri (puri:uri "https://wikimedia.org"))) (setf (puri:uri-path uri) (concatenate 'string "/" (drakma:url-encode "/кадабра" :utf-8))) uri) 生产:

    #<PURI:URI https://wikimedia.org/%D0%BA%D0%B0%D0%B4%D0%B0%D0%B1%D1%80%D0%B0>
    
    然后,Drakma接受此URI而不进行任何额外处理。