Categorías > Lenguajes > Common LISP > HTTP Parser ...
Nuevo Mensaje | Responder
Sorancio


307 envíos
Desconectado
1453 lecturas
0 respuestas
HTTP Parser13-05-2010 a las 14:24:21

Para practicar CL me he puesto a hacer un pequeño parser de HTTP, lo publico aquí para ver si alguien se interesa y gano adeptos para seguir con el tutorial .

Código Fuente:
(defun split-http-headers (http-headers)
  "Split HTTP headers and returns a list of them"
  (loop for i = 0 then (1+ j)
        as j = (position #Newline http-headers :start i)
        collect (subseq http-headers i j)
        while j))

(defun http-parse-header (string)
  "Parses an HTTP header and returns a cell (header . value)"
  (let ((separator-position (position #: string)))
    (if (numberp separator-position)
        (cons (subseq string 0 separator-position)
              (string-left-trim " " (subseq string (1+ separator-position))))
      nil)))

(defun parse-http-headers (http-headers)
  "Returns a list of cells (header . value)"
  (let ((headers (split-http-headers http-headers)))
    (loop for i in headers
          collect (http-parse-header i))))

(defun split-http-message (http-message)
  "Returns a cell (headers . body-content)"
  (let ((separator-position (search (format nil "~%~%") http-message)))
    (if (numberp separator-position)
        (cons (subseq http-message 0 separator-position)
              (subseq http-message (+ 2 separator-position)))
      nil)))

(defun parse-http-message-info (http-raw-message)
  "Parses an HTTP message and returns a cell (headers . body)"
  (let ((http-message (split-http-message http-raw-message)))
    (cons (parse-http-headers (car http-message))
          (cdr http-message))))

(defun parse-http-client-request-info (request-line)
  "Returns a list (METHOD URL VERSION)"
  (let ((iterator (position #Space request-line))
        return-list)
    (push (subseq request-line 0 iterator) return-list)
    (push (subseq request-line (1+ iterator)
                  (position #Space request-line
                            :start (1+ iterator))) return-list)
    (setq iterator (search "HTTP/" request-line))
    (push (subseq request-line (+ iterator 5)) return-list)
    (reverse return-list)))

(defun parse-http-server-response-info (response-line)
  "Returns a list (VERSION RESPONSE-NUMBER RESPONSE-STRING"
  (let ((iterator (search "HTTP/" response-line))
        return-list)
    (push (subseq response-line (+ iterator 5)
                  (position #Space response-line :start (+ iterator 5)))
          return-list)
    (setq iterator (position #Space response-line))
    (push (subseq response-line (1+ iterator)
                  (position #Space response-line :start (1+ iterator)))
          return-list)
    (setq iterator (position #Space response-line :start (1+ iterator)))
    (push (subseq response-line (1+ iterator)) return-list)
    (reverse return-list)))

(defun parse-http-message (message type)
  "Returns a cell (PARSED-RESPONSE . (HEADERS . BODY))"
  (let ((first-line-end (position #Newline message))
        first-line rest parsed-response)
    (setq first-line (subseq message 0 first-line-end))
    (setq rest (subseq message (1+ first-line-end)))
    (if (string= type "request")
        (setq parsed-response (cons
                          (parse-http-client-request-info first-line)
                          nil))
      (setq parsed-response (cons
                            (parse-http-server-response-info first-line)
                            nil)))
    (cons (car parsed-response) (parse-http-message-info rest))))


Uso:

( parse-http-message "MENSAJE" "request"/"response" )

Edit: Cualquier duda o comentario para eso esta el foro mensaje y ale.


Responder | Citar | Moderar | Mensaje Privado
Training Channel
Este mensaje no tiene respuestas