Emacs25.1之后UrlHttpError

*/-->

pre.src {background-color: #002b36; color: #839496;}

pre.src {background-color: #002b36; color: #839496;}

pre.src {background-color: #002b36; color: #839496;}

pre.src {background-color: #002b36; color: #839496;}

pre.src {background-color: #002b36; color: #839496;}

pre.src {background-color: #002b36; color: #839496;}

pre.src {background-color: #002b36; color: #839496;}

pre.src {background-color: #002b36; color: #839496;}

pre.src {background-color: #002b36; color: #839496;}

pre.src {background-color: #002b36; color: #839496;}

Emacs25.1之后UrlHttpError

Table of Contents

1 引言

当我们更新到Emacs25.1或者之后的版本后,原来可以使用的org2blog,或者其他类似使用metaweblog包的功能都无法使用了,会报一个"error: url-http-create-request: Multibyte text in HTTP request" 的错误信息。

这个问题出现之后,由于我用的是cnblogs插件,这个插件作者很久没有更新了,我首先想到的是这个插件是不是出问题了。然后,我把这个插件查找了,发现不是这个里面的问题。于是在google上搜索了一下,发现其他有好多人也在问这个问题(主要是日本的,说明emacs在日本使用普及度应该比中国要高很多)。

2 正文

在网上并没有找到解决方案,于是,我就决定自己去查看一下Emacs的url-http的源码:

c:/emacs/share/emacs/26.0.50/lisp/url/url-http.el.gz

然后,发现在第395行的位置,有这么一段代码:

;; Bug#23750
(unless (= (string-bytes request)
(length request))
(error "Multibyte text in HTTP request: %s" request))

无疑就是这个地方报的错,为什么会报错呢?

去看一下之前版本的代码就知道了,原来是没有这几行代码的,作者也标明了,加入这几行代码是为了解决 Bug#23750,而这个bug我也去查了一下,应该是json.el中的一个bug,也就是说,如果代码不在这个地方检查报错,后面如果要使用到json中的函数的话,同样也会报错,并且据介绍,会更加隐晦,更难查找(去搜索json中的中文问题)。所以,作者在这里提前报错。

那这个错误到底是什么呢?

就是说 (string-bytes request)(length request) 的返回值不一样的时候,就会报错。而中文字符的string-bytes,如果用utf-8来进行编码的话,字符长度是变化的,中文的编码平均大概是每个字会占用3个bytes,而 length 函数返回的会是1。那结果当然是不相等,当然会报错了。

怎么解决呢?一个简单的方法是:

;; Bug#23750
(setq request (url-http--encode-string request))
(unless (= (string-bytes request)
(length request))
(error "Multibyte text in HTTP request: %s" request))

其中的 url-http--encode-string 也是作者新增的:

(defun url-http--encode-string (s)
(if (multibyte-string-p s)
(encode-coding-string s 'us-ascii)
s))

把传进来的中文先转换为'us-ascii编码,这样,两种函数返回值就是相等的了。 当然,为什么可以这样,把中文转换为ascii,照理压根儿就不可行吧?这里没有想明白。但是可以工作了,是不是作用只是把这个判断跳过去了,后面使用json还是会报错?这个目前还没有去测试。 但是,确实是可以工作了,我目前的这个文章就是使用这个来发布的。

完整的函数,把它添加到配置文件中去就可以了:

(defun url-http-create-request (&optional ref-url)
"Create an HTTP request for `url-http-target-url', referred to by REF-URL."
(let* ((extra-headers)
(request nil)
(no-cache (cdr-safe (assoc "Pragma" url-http-extra-headers)))
(using-proxy url-http-proxy)
(proxy-auth (if (or (cdr-safe (assoc "Proxy-Authorization"
url-http-extra-headers))
(not using-proxy))
nil
(let ((url-basic-auth-storage
'url-http-proxy-basic-auth-storage))
(url-get-authentication url-http-proxy nil 'any nil))))
(real-fname (url-filename url-http-target-url))
(host (url-http--encode-string (url-host url-http-target-url)))
(auth (if (cdr-safe (assoc "Authorization" url-http-extra-headers))
nil
(url-get-authentication (or
(and (boundp 'proxy-info)
proxy-info)
url-http-target-url) nil 'any nil))))
(if (equal "" real-fname)
(setq real-fname "/"))
(setq no-cache (and no-cache (string-match "no-cache" no-cache)))
(if auth
(setq auth (concat "Authorization: " auth "\r\n")))
(if proxy-auth
(setq proxy-auth (concat "Proxy-Authorization: " proxy-auth "\r\n"))) ;; Protection against stupid values in the referrer
(if (and ref-url (stringp ref-url) (or (string= ref-url "file:nil")
(string= ref-url "")))
(setq ref-url nil)) ;; We do not want to expose the referrer if the user is paranoid.
(if (or (memq url-privacy-level '(low high paranoid))
(and (listp url-privacy-level)
(memq 'lastloc url-privacy-level)))
(setq ref-url nil)) ;; url-http-extra-headers contains an assoc-list of
;; header/value pairs that we need to put into the request.
(setq extra-headers (mapconcat
(lambda (x)
(concat (car x) ": " (cdr x)))
url-http-extra-headers "\r\n"))
(if (not (equal extra-headers ""))
(setq extra-headers (concat extra-headers "\r\n"))) ;; This was done with a call to `format'. Concatenating parts has
;; the advantage of keeping the parts of each header together and
;; allows us to elide null lines directly, at the cost of making
;; the layout less clear.
(setq request
(concat
;; The request
(or url-http-method "GET") " "
(url-http--encode-string
(if using-proxy (url-recreate-url url-http-target-url) real-fname))
" HTTP/" url-http-version "\r\n"
;; Version of MIME we speak
"MIME-Version: 1.0\r\n"
;; (maybe) Try to keep the connection open
"Connection: " (if (or using-proxy
(not url-http-attempt-keepalives))
"close" "keep-alive") "\r\n"
;; HTTP extensions we support
(if url-extensions-header
(format
"Extension: %s\r\n" url-extensions-header))
;; Who we want to talk to
(if (/= (url-port url-http-target-url)
(url-scheme-get-property
(url-type url-http-target-url) 'default-port))
(format
"Host: %s:%d\r\n" (puny-encode-domain host)
(url-port url-http-target-url))
(format "Host: %s\r\n" (puny-encode-domain host)))
;; Who its from
(if url-personal-mail-address
(concat
"From: " url-personal-mail-address "\r\n"))
;; Encodings we understand
(if (or url-mime-encoding-string
;; MS-Windows loads zlib dynamically, so recheck
;; in case they made it available since
;; initialization in url-vars.el.
(and (eq 'system-type 'windows-nt)
(fboundp 'zlib-available-p)
(zlib-available-p)
(setq url-mime-encoding-string "gzip")))
(concat
"Accept-encoding: " url-mime-encoding-string "\r\n"))
(if url-mime-charset-string
(concat
"Accept-charset: "
(url-http--encode-string url-mime-charset-string)
"\r\n"))
;; Languages we understand
(if url-mime-language-string
(concat
"Accept-language: " url-mime-language-string "\r\n"))
;; Types we understand
"Accept: " (or url-mime-accept-string "*/*") "\r\n"
;; User agent
(url-http-user-agent-string)
;; Proxy Authorization
proxy-auth
;; Authorization
auth
;; Cookies
(when (url-use-cookies url-http-target-url)
(url-http--encode-string
(url-cookie-generate-header-lines
host real-fname
(equal "https" (url-type url-http-target-url)))))
;; If-modified-since
(if (and (not no-cache)
(member url-http-method '("GET" nil)))
(let ((tm (url-is-cached url-http-target-url)))
(if tm
(concat "If-modified-since: "
(url-get-normalized-date tm) "\r\n"))))
;; Whence we came
(if ref-url (concat
"Referer: " ref-url "\r\n"))
extra-headers
;; Length of data
(if url-http-data
(concat
"Content-length: " (number-to-string
(length url-http-data))
"\r\n"))
;; End request
"\r\n"
;; Any data
url-http-data))
;; Bug#23750
(setq request (url-http--encode-string request))
(unless (= (string-bytes request)
(length request))
(error "Multibyte text in HTTP request: %s" request))
(url-http-debug "Request is: \n%s" request)
request))

3 参考资源

《使用org-mode写cnblogs博客》:

http://www.cnblogs.com/yangwen0228/p/6238723.html

配置github地址:

https://github.com/yangwen0228/unimacs

Date: 2017-01-08 10:50

Created: 2017-01-08 周日 11:37

Validate

Emacs25.1之后UrlHttpError的更多相关文章

  1. CentOS 6.7 中安装Emacs 24.5

    Emacs 版本:http://mirror.bjtu.edu.cn/gnu/emacs/emacs-24.5.tar.gz CentOS 内核版本:2.6.32-573.el6.x86_64 参考资 ...

  2. CentOS编译安装emacs并配置

    Liunxs中CentOS系列一向以稳定为目标,然而也会存在版本太旧的问题,emacs就是其中的一个,目前emacs都发行到25.2了,而CentOS上的emacs版本却还是23.1.所以需要下载源代 ...

  3. windows 配置 Scheme + Emacs 编程环境

    软件下载列表: Emacs Racket (这里使用 Racket ,更加方便,便于后面配置 Emacs) 配置 安装好 Emacs 后,在 C:\Users\用户名\AppData\Roaming\ ...

  4. Top 10 JavaScript编辑器,你在用哪个?

    对于JavaScript程序员来说,目前有很多很棒的工具可供选择.文本将会讨论10个优秀的支持JavaScript,HTML5和CSS开发,并且可以使用Markdown进行文档编写的文本编辑器.为什么 ...

  5. CentOS 中安装和卸载 Emacs

    日志更新记录: [1] 增加 CentOS7.2 (内核版本:3.10.0-514.16.1.el7.x86_64)下Emacs25.2 的安装过程,它与本文的步骤完全一样. Emacs 版本:htt ...

  6. 命令更新emacs

    sudo apt-add-repository -y ppa:adrozdoff/emacs sudo apt update sudo apt install emacs25

  7. Ubuntu 17.10 环境初始化

    输入法(中文) sogoupinyin fcitx-table-wubi 输入法快捷键 Ctrl + Space(两个间切换), Ctrl + Shift(多个间切换), Shift中英切换 与Win ...

  8. emacs安装

    1.我选用的是Ubuntu16.04. 2.Ubuntu安装好之后不能直接sudo apt-get install emacs,因为Ubuntu的源默认是emacs24,最好是用最新的emacs25, ...

  9. win32获取浏览器当前Tab的URL

    代码都是win10上测试的 1. 获取IE的URL,Enum IE窗口的子句柄,找到className为Edit的句柄,然后用SendMessage WM_GETTEXT消息来获取: 上代码: #in ...

随机推荐

  1. python打开文件失败,报错'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence

    python3.7,python3.6都存在的问题: 读取的文件编码是utf-8 第1行是空行.#开头都可能会报这个错误: E:\count_packet>python string_count ...

  2. MySQL总结03

    MySQL表的引擎常用的有两种:MyISAM.InnoDB MyISAM引擎 MySQL5.5之前数据库默认的存储引擎都是MyISAM,MySQL5.5之后(包括5.5)用的是InnoDB. 每一个M ...

  3. 插件化框架解读之Class文件与Dex文件的结构(一)

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 Class文件 Class文件是Java虚拟机定义并被其所识别的 ...

  4. CTU Open 2018 Lighting /// 组合数递推 二进制

    题目大意: 给定n k 给定一个数的二进制位a[] 求这个数加上 另一个二进制位<=n的数b 后 能得到多少个不同的 二进制位有k个1 的数 样例 input10 51000100111 out ...

  5. 第五节 RabbitMQ在C#端的应用-消息收发

    原文:第五节 RabbitMQ在C#端的应用-消息收发 版权声明:未经本人同意,不得转载该文章,谢谢 https://blog.csdn.net/phocus1/article/details/873 ...

  6. PascalCase & camelCase & kebabCase

    帕斯卡拼写法( 也叫大骆驼拼写法),一种计算机编程中的变量命名方法.它主要的特点是将描述变量作用所有单词的首字母大写,然后直接连接起来,单词之间没有连接符.比如: Age LastName Winte ...

  7. 分支结构case 语句举例

  8. 转载:java面试题(二)

    这部分主要是开源Java EE框架方面的内容,包括Hibernate.MyBatis.Spring.Spring MVC等,由于Struts 2已经是明日黄花,在这里就不讨论Struts 2的面试题, ...

  9. 割边的tarjan算法

    与割点唯一一点不同是low[v]>=dfn[u]变为low[v]>dfn[u] 代码如下: bool vis[maxn]; int dfn[maxn],low[maxn]; int cnt ...

  10. 使用pytorch测试单张图片(test single image with pytorch)

    以下代码实现使用pytorch测试一张图片 引用文章: https://www.learnopencv.com/pytorch-for-beginners-image-classification-u ...