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. luoguP1080 国王游戏 题解(NOIP2012)(贪心+高精)

    luoguP1080 国王游戏 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include& ...

  2. Logstash,Fluentd, Logtail对比伤害

    摘要: 针对主流日志采集客户端(Logstash,Fluentd,以及日志服务客户端Logtail)进行功能.性能和稳定性测评 日志收集的场景 DT时代,数以亿万计的服务器.移动终端.网络设备每天产生 ...

  3. python isinstance()函数和type()函数

    一.type()用法 描述: python的 type 函数有两个用法,当只有一个参数的时候,返回对象的类型.当有三个参数的时候返回一个类对象. 语法: 一个参数:type(object) 三个参数: ...

  4. sublime中使用插件anaconda而在代码中出现方框

    这个标志是说不符合PEP8标准,比如使用了Tab做缩进:一行过长等问题. 可以在可以在 Sublime > Preferences > Package Settings > Anac ...

  5. bootstrap-thymeleaf-分页

    1.HTML代码 <div th:fragment="paginater"> <ul th:id="paginaterUlID" th:if= ...

  6. Droppable(放置组件)

    一.class加载方式 <div id="pop" class="easyui-droppable" style="width: 400px;h ...

  7. WPF绑定のRelativeSource

    在WPF绑定的时候,指定绑定源时,有一种办法是使用RelativeSource. 这种办法的意思是指当前元素和绑定源的位置关系. 第一种关系: Self 举一个最简单的例子:在一个StackPanel ...

  8. GeneXus笔记本—获取当月的最后一天

    首先获取当前日期 然后赋值为当前年月的第一天  然后加一个月 减去一天 就是当月最后一天 多用于筛选数据时的条件或者区间 我们先随便拉个页面  简单点就好 放入两个textblock 然后点击Even ...

  9. 【转载】MySQL count(*) count(1) count(column)区别

    MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个数,效率很高 InnoDB 引擎执行 count(*) 的时候,需要把数据一行一行地从引擎里面读出来,然 ...

  10. PostgreSQL的学习-序列

    序列对象(也叫序列生成器)都是用CREATE SEQUENCE创建的特殊的单行表.一个序列对象通常用于为行或者表生成唯一的标识符.下面序列函数,为我们从序列对象中获取最新的序列值提供了简单和并发读取安 ...