From: Eric Schulte Date: Sat, 21 Dec 2013 02:22:31 +0000 (-0700) Subject: url-encoded parameters X-Git-Url: https://code.delx.au/gnu-emacs-elpa/commitdiff_plain/e44dc579f213a7f80a8ebdcc5805fcf0170abf18?ds=sidebyside url-encoded parameters --- diff --git a/NOTES b/NOTES index 07e73055e..2b163c4fb 100644 --- a/NOTES +++ b/NOTES @@ -1,7 +1,7 @@ -*- org -*- * Notes -* Tasks [4/8] +* Tasks [5/8] ** DONE Handle POST requests 1. read standard for POST data 2. parse multi-line headers with boundaries @@ -22,8 +22,8 @@ parse more than just the content-type headers. ** DONE non-multipart form data e.g., parameter strings -** TODO some more convenience functionality [5/6] -- [ ] strip and parse URL query string +** DONE some more convenience functionality [6/6] +- [X] strip and parse URL query string - [X] parse urlencoded post data - [X] think about defaulting to (name . content) for form elements - [X] maybe don't require a non-nil return to cancel the connection, diff --git a/emacs-web-server.el b/emacs-web-server.el index 2ceaf3953..2d276d58e 100644 --- a/emacs-web-server.el +++ b/emacs-web-server.el @@ -10,6 +10,7 @@ (require 'emacs-web-server-status-codes) (require 'mail-parse) ; to parse multipart data in headers (require 'mm-encode) ; to look-up mime types for files +(require 'url-util) ; to decode url-encoded params (require 'eieio) (eval-when-compile (require 'cl)) (require 'cl-lib) @@ -112,8 +113,13 @@ function. (cl-flet ((to-keyword (s) (intern (concat ":" (upcase (match-string 1 s)))))) (cond ((string-match ews-http-method-rx string) - (list (cons (to-keyword (match-string 1 string)) (match-string 2 string)) - (cons :TYPE (match-string 3 string)))) + (let ((method (to-keyword (match-string 1 string))) + (url (match-string 2 string))) + (if (string-match "?" url) + (cons (cons method (substring url 0 (match-beginning 0))) + (url-parse-query-string (url-unhex-string + (substring url (match-end 0))) )) + (list (cons method url))))) ((string-match "^\\([^[:space:]]+\\): \\(.*\\)$" string) (list (cons (to-keyword string) (match-string 2 string)))) (:otherwise (ews-error proc "bad header: %S" string) nil)))) @@ -165,13 +171,9 @@ function. (throw 'finished-parsing-headers t)) ;; Parse a URL ((eq boundary :application/x-www-form-urlencoded) - (mapc (lambda (p) - (when (string-match "=" p) - (setcdr (last headers) - (list (cons (substring p 0 (match-beginning 0)) - (substring p (match-end 0))))))) - (split-string (ews-trim (substring pending last-index)) - "&" 'omit-nulls)) + (mapc (lambda (pair) (setcdr (last headers) (list pair))) + (url-parse-query-string + (ews-trim (substring pending last-index)))) (throw 'finished-parsing-headers t)) ;; Build up multipart data. (boundary diff --git a/examples/5-url-param-echo.el b/examples/5-url-param-echo.el new file mode 100644 index 000000000..00c2e1715 --- /dev/null +++ b/examples/5-url-param-echo.el @@ -0,0 +1,26 @@ +;;; url-param-echo.el --- echo back url-paramed message using Emacs Web Server + +;; Copyright (C) 2013 Eric Schulte + +;; Author: Eric Schulte +;; Keywords: http url-param +;; License: GPLV3 (see the COPYING file in this directory) + +;;; Code: +(require 'emacs-web-server) + +(ews-start + '(((:GET . ".*") . + (lambda (proc request) + (ews-response-header proc 200 '("Content-type" . "text/html")) + (process-send-string proc + (concat "URL Parameters:
" + (mapconcat (lambda (pair) + (format "" + (car pair) + (mapconcat #'identity (cdr pair) " "))) + (cl-remove-if-not (lambda (el) (stringp (car el))) + request) + "") + "
%s%s
"))))) + 9005)