Secure raw url handler

Evgeny PisemskySun Feb 16 11:30:00+0300 2025

0a22a74

Secure raw url handler

pastebin/data.scm

33
(use-modules (srfi srfi-9)
44
             (srfi srfi-1)
55
             (ice-9 ftw)
6+
             (ice-9 regex)
67
             (ice-9 textual-ports))
78
89
(export <pb-data>
910
        <pb-entry>
1011
        pb-entry-id
12+
        pb-entry-id-valid?
1113
        pb-entry-text
1214
        pb-data-open
1315
        pb-data-close

2729
  (id pb-entry-id set-pb-entry-id!)
2830
  (text pb-entry-text set-pb-entry-text!))
2931
32+
(define (pb-entry-id-valid? id)
33+
  (and (= (string-length id) 5)
34+
       (string-match "[0-9A-Za-z]{5}" id)
35+
       #t))
36+
3037
;; input: dir: string
3138
;; output: <pb-data>
3239
(define (pb-data-open dir)

pastebin/httpserver.scm

108108
      (values (build-response #:code 400)
109109
              (lambda (port) 1))))
110110
111+
(define (raw-handler pb-data-path pb-id)
112+
  (if (pb-entry-id-valid? pb-id)
113+
      (values (build-response
114+
               #:code 200
115+
               #:headers '((content-type . (text/plain))))
116+
              (lambda (port)
117+
                (call-with-input-file
118+
                    ;; the file name
119+
                    (call-with-dir-as-pb-data
120+
                     pb-data-path
121+
                     (lambda (p) (pb-get-file-path p pb-id)))
122+
                  ;; the input port
123+
                  (lambda (inport)
124+
                    (let A ((inport' inport))
125+
                      (let ((bv (get-bytevector-n inport' 4096)))
126+
                        (if (not (eof-object? bv))
127+
                            (begin
128+
                              (put-bytevector port bv)
129+
                              (A inport')))))))))
130+
      (values (build-response #:code 404)
131+
              (lambda (port) 1))))
132+
111133
(define (make-pastebin-handler data-path)
112134
  (lambda (request request-body)
113135
    (match (split-and-decode-uri-path (uri-path (request-uri request)))

118140
119141
      ;; URI: /raw/<id> -- return raw content of the paste
120142
      (("raw" pb-id)
121-
       (values (build-response
122-
                #:code 200
123-
                #:headers '((content-type . (text/plain))))
124-
125-
               (lambda (port)
126-
                 (call-with-input-file
127-
                     ;; the file name
128-
                     (call-with-dir-as-pb-data
129-
                      data-path
130-
                      (lambda (p) (pb-get-file-path p pb-id)))
131-
132-
                   ;; the input port
133-
                   (lambda (inport)
134-
                     (let A ((inport' inport))
135-
                       (let ((bv (get-bytevector-n inport' 4096)))
136-
                         (if (not (eof-object? bv))
137-
                             (begin
138-
                               (put-bytevector port bv)
139-
                               (A inport'))))))))))
143+
       (raw-handler data-path pb-id))
140144
141145
      ;; URI: * -- everything else -- show the top 5 paste list
142146
      (_