Mercurial > dotfiles
comparison .elisp/http-twiddle.el @ 143:35eef880a5ac
emacs: add http-twiddle for POST debugging
author | Augie Fackler <durin42@gmail.com> |
---|---|
date | Thu, 17 Sep 2009 10:33:59 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
142:daceba28ace4 | 143:35eef880a5ac |
---|---|
1 ;;; http-twiddle.el -- send & twiddle & resend HTTP requests | |
2 ;; | |
3 ;; Version 1.0 written by Luke Gorrie <luke@synap.se> in February 2006 | |
4 ;; This program belongs to the public domain. | |
5 ;; | |
6 ;; (downloaded from http://fresh.homeunix.net/~luke/misc/emacs/http-twiddle.el) | |
7 ;; | |
8 ;; This is a program for testing hand-written HTTP requests. You write | |
9 ;; your request in an Emacs buffer (using http-twiddle-mode) and then | |
10 ;; press `C-c C-c' each time you want to try sending it to the server. | |
11 ;; This way you can interactively debug the requests. To change port or | |
12 ;; destination do `C-u C-c C-c'. | |
13 ;; | |
14 ;; The program is particularly intended for the POST-"500 internal | |
15 ;; server error"-edit-POST loop of integration with SOAP programs. | |
16 ;; | |
17 ;; The mode is activated by `M-x http-twiddle-mode' or automatically | |
18 ;; when opening a filename ending with .http-twiddle. | |
19 ;; | |
20 ;; The request can either be written from scratch or you can paste it | |
21 ;; from a snoop/tcpdump and then twiddle from there. | |
22 ;; | |
23 ;; See the documentation for the `http-twiddle-mode' and | |
24 ;; `http-twiddle-mode-send' functions below for more details and try | |
25 ;; `M-x http-twiddle-mode-demo' for a simple get-started example. | |
26 ;; | |
27 ;; Tested with GNU Emacs 21.4.1 and not tested/ported on XEmacs yet. | |
28 | |
29 ;;; Example buffer: | |
30 | |
31 ;; POST / HTTP/1.0 | |
32 ;; Connection: close | |
33 ;; Content-Length: $Content-Length | |
34 ;; | |
35 ;; The request body goes here | |
36 | |
37 (require 'font-lock) ; faces | |
38 | |
39 (eval-when-compile | |
40 (unless (fboundp 'define-minor-mode) | |
41 (require 'easy-mmode) | |
42 (defalias 'define-minor-mode 'easy-mmode-define-minor-mode)) | |
43 (require 'cl)) | |
44 | |
45 (define-minor-mode http-twiddle-mode | |
46 "Major mode for twiddling around with HTTP requests and sending them. | |
47 Use `http-twiddle-mode-send' (\\[http-twiddle-mode-send]) to send the request." | |
48 nil | |
49 " http-twiddle" | |
50 '(("\C-c\C-c" . http-twiddle-mode-send))) | |
51 | |
52 (defvar http-twiddle-show-request t | |
53 "*Show the request in the transcript.") | |
54 | |
55 (add-to-list 'auto-mode-alist '("\\.http-twiddle$" . http-twiddle-mode)) | |
56 | |
57 (defvar http-twiddle-endpoint nil | |
58 "Cache of the (HOST PORT) to send the request to.") | |
59 | |
60 (defvar http-twiddle-process nil | |
61 "Socket connected to the webserver.") | |
62 | |
63 (defvar http-twiddle-port-history '() | |
64 "History of port arguments entered in the minibuffer. | |
65 \(To make XEmacs happy.)") | |
66 | |
67 (defvar http-twiddle-host-history '() | |
68 "History of port arguments entered in the minibuffer. | |
69 \(To make XEmacs happy.)") | |
70 | |
71 (defun http-twiddle-mode-send (host port) | |
72 "Send the current buffer to the server. | |
73 Linebreaks are automatically converted to CRLF (\\r\\n) format and any | |
74 occurences of \"$Content-Length\" are replaced with the actual content | |
75 length." | |
76 (interactive (http-twiddle-read-endpoint)) | |
77 ;; close any old connection | |
78 (when http-twiddle-process | |
79 (kill-buffer (process-buffer http-twiddle-process))) | |
80 (let ((content (buffer-string))) | |
81 (with-temp-buffer | |
82 (insert content) | |
83 (http-twiddle-convert-cr-to-crlf) | |
84 (http-twiddle-expand-content-length) | |
85 (let ((request (buffer-string))) | |
86 (setq http-twiddle-process | |
87 (open-network-stream "http-twiddle" "*HTTP Twiddle*" host port)) | |
88 (set-process-filter http-twiddle-process 'http-twiddle-process-filter) | |
89 (set-process-sentinel http-twiddle-process 'http-twiddle-process-sentinel) | |
90 (process-send-string http-twiddle-process request) | |
91 (save-selected-window | |
92 (pop-to-buffer (process-buffer http-twiddle-process)) | |
93 (when http-twiddle-show-request | |
94 (insert request) | |
95 (set-window-start (selected-window) (point)) | |
96 (add-text-properties (point-min) (point-max) | |
97 '(face font-lock-comment-face))) | |
98 (set-mark (point))))))) | |
99 | |
100 (defun http-twiddle-read-endpoint () | |
101 "Return the endpoint (HOST PORT) to send the request to." | |
102 (if (and http-twiddle-endpoint (null current-prefix-arg)) | |
103 http-twiddle-endpoint | |
104 (setq http-twiddle-endpoint | |
105 (list (read-string "Host: (default localhost) " | |
106 nil 'http-twiddle-host-history "localhost") | |
107 (let ((input (read-from-minibuffer "Port: " nil nil t 'http-twiddle-port-history))) | |
108 (if (integerp input) | |
109 input | |
110 (error "Not an integer: %S" input))))))) | |
111 | |
112 (defun http-twiddle-convert-cr-to-crlf () | |
113 "Convert \\n linebreaks to \\r\\n in the whole buffer." | |
114 (save-excursion | |
115 (goto-char (point-min)) | |
116 (while (re-search-forward "[^\r]\n" nil t) | |
117 (backward-char) | |
118 (insert "\r")))) | |
119 | |
120 (defun http-twiddle-expand-content-length () | |
121 "Replace any occurences of $Content-Length with the actual Content-Length." | |
122 (save-excursion | |
123 (goto-char (point-min)) | |
124 (let ((content-length | |
125 (save-excursion (when (search-forward "\r\n\r\n" nil t) | |
126 (- (point-max) (point)))))) | |
127 (unless (null content-length) | |
128 (let ((case-fold-search t)) | |
129 (while (search-forward "$content-length" nil t) | |
130 (replace-match (format "%d" content-length) nil t))))))) | |
131 | |
132 (defun http-twiddle-process-filter (process string) | |
133 "Process data from the socket by inserting it at the end of the buffer." | |
134 (with-current-buffer (process-buffer process) | |
135 (goto-char (point-max)) | |
136 (insert string))) | |
137 | |
138 (defun http-twiddle-process-sentinel (process what) | |
139 (with-current-buffer (process-buffer process) | |
140 (goto-char (point-max)) | |
141 (let ((start (point))) | |
142 (insert "Connection closed\n") | |
143 (add-text-properties start (point) '(face font-lock-string-face))))) | |
144 | |
145 (defun http-twiddle-mode-demo () | |
146 (interactive) | |
147 (pop-to-buffer (get-buffer-create "*http-twiddle demo*")) | |
148 (http-twiddle-mode 1) | |
149 (erase-buffer) | |
150 (insert "POST / HTTP/1.0\nContent-Length: $Content-Length\nConnection: close\n\nThis is the POST body.\n") | |
151 (message "Now press `C-c C-c' and enter a webserver address (e.g. google.com port 80).")) | |
152 | |
153 (provide 'http-twiddle) |