Parcourir la Source

escaping urls

bmallred 9 ans auparavant
Parent
Commettre
44bc9bbeca
2 fichiers modifiés avec 36 ajouts et 9 suppressions
  1. 23 1
      handlers/content.go
  2. 13 8
      html/workspace.html

+ 23 - 1
handlers/content.go

@ -5,6 +5,7 @@ import (
5 5
	"html/template"
6 6
	"log"
7 7
	"net/http"
8
	"net/url"
8 9
	"time"
9 10
10 11
	"code.revolvingcow.com/revolvingcow/loop/account"
@ -69,12 +70,16 @@ func ContentCreateHandler(w http.ResponseWriter, r *http.Request) {
69 70
	vars := mux.Vars(r)
70 71
	title := vars["title"]
71 72
	if title != "" {
73
		title, err = url.QueryUnescape(title)
74
		if err != nil {
75
			http.Error(w, err.Error(), http.StatusInternalServerError)
76
		}
72 77
		account.Add(title, "document.md", []byte{})
73 78
	} else {
74 79
		http.Redirect(w, r, account.Username, http.StatusSeeOther)
75 80
	}
76 81
77
	http.Redirect(w, r, "/"+account.Username+"/edit/"+title, http.StatusSeeOther)
82
	http.Redirect(w, r, "/"+account.Username+"/edit/"+url.QueryEscape(title), http.StatusSeeOther)
78 83
}
79 84
80 85
// ContentReadHandler reads a document in the user context.
@ -94,6 +99,10 @@ func ContentReadHandler(w http.ResponseWriter, r *http.Request) {
94 99
		http.Error(w, "No title given", http.StatusInternalServerError)
95 100
		return
96 101
	}
102
	title, err = url.QueryUnescape(title)
103
	if err != nil {
104
		http.Error(w, err.Error(), http.StatusInternalServerError)
105
	}
97 106
98 107
	contents, err := account.Read(title)
99 108
	if err != nil {
@ -128,6 +137,11 @@ func ContentPreviewHandler(w http.ResponseWriter, r *http.Request) {
128 137
129 138
	vars := mux.Vars(r)
130 139
	title := vars["title"]
140
	title, err = url.QueryUnescape(title)
141
	if err != nil {
142
		http.Error(w, err.Error(), http.StatusInternalServerError)
143
	}
144
131 145
	contents := r.FormValue("contents")
132 146
	if contents == "" {
133 147
		contents, _ = account.Read(title)
@ -162,6 +176,10 @@ func ContentUpdateHandler(w http.ResponseWriter, r *http.Request) {
162 176
		http.Error(w, "No title given", http.StatusInternalServerError)
163 177
		return
164 178
	}
179
	title, err = url.QueryUnescape(title)
180
	if err != nil {
181
		http.Error(w, err.Error(), http.StatusInternalServerError)
182
	}
165 183
166 184
	contents := r.FormValue("contents")
167 185
	if contents == "" {
@ -194,6 +212,10 @@ func ContentDeleteHandler(w http.ResponseWriter, r *http.Request) {
194 212
		http.Error(w, "No title given", http.StatusInternalServerError)
195 213
		return
196 214
	}
215
	title, err = url.QueryUnescape(title)
216
	if err != nil {
217
		http.Error(w, err.Error(), http.StatusInternalServerError)
218
	}
197 219
198 220
	account.Remove(title)
199 221
	http.Redirect(w, r, "/"+account.Username, http.StatusSeeOther)

+ 13 - 8
html/workspace.html

@ -72,6 +72,7 @@
72 72
{{ end }}
73 73
{{ define "content" }}
74 74
    <div class="row">
75
75 76
        <div id="left-pane" class="col s4 m4 l2">
76 77
            <div class="row">
77 78
                <div class="col s12">
@ -91,7 +92,7 @@
91 92
                        {{ range $d := .Directories }}
92 93
                            <li class="collection-item avatar dismissable">
93 94
                                <i class="mdi-file-folder circle"></i>
94
                                <span class="title"><a href="/{{ $.Username }}/edit/{{ $d }}">{{ $d }}</a></span>
95
                                <span class="title"><a href="/{{ $.Username }}/edit/{{ $d | urlquery }}">{{ $d }}</a></span>
95 96
                                <p><!--(3 files)--></p>
96 97
                                <a href="#" class="secondary-content"><i class="mdi-action-grade"></i></a>
97 98
                            </li>
@ -100,6 +101,7 @@
100 101
                </div>
101 102
            </div>
102 103
        </div>
104
103 105
        <div id="workarea" class="col s8 m8 l10">
104 106
            <div class="fixed-action-btn" style="bottom: 45px; right: 24px;">
105 107
                <a id="create" class="btn-floating btn-large red" title="Edit">
@ -128,7 +130,7 @@
128 130
                    </div>
129 131
                    <div class="col s12 m12 l12"><h4>{{ .Title }}</h4></div>
130 132
                    <pre id="editor" class="col s12 m12 l12">{{ .Content }}</pre>
131
                    <iframe id="view" class="col s12 m12 l12" style="display: none;" frameBorder="0" seamless="seamless" src="/{{ .Username }}/edit/{{ .Title }}/preview"></iframe>
133
                    <iframe id="view" class="col s12 m12 l12" style="display: none;" frameBorder="0" seamless="seamless" src="/{{ .Username }}/edit/{{ .Title | urlquery }}/preview"></iframe>
132 134
                </div>
133 135
            {{ else }}
134 136
                <div class="row">
@ -139,6 +141,7 @@
139 141
            {{ end }}
140 142
        </div>
141 143
    </div>
144
142 145
    <div class="row">
143 146
        <div class="col s12">
144 147
            <div id="upload-area" class="modal bottom-sheet">
@ -161,6 +164,7 @@
161 164
            </div>
162 165
        </div>
163 166
    </div>
167
164 168
    <div id="modal-new-directory" class="modal">
165 169
        <div class="modal-content">
166 170
            <h4>New Content</h4>
@ -341,14 +345,15 @@
341 345
                });
342 346
            });
343 347
348
            $('form#new-directory').submit(function (event) {
349
                var title = $('input#title').val();
350
                var action = $(this).attr('action');
351
                $(this).attr('action', action + encodeURIComponent(title));
352
                return true;
353
            });
344 354
            $('a#new').click(function (event) {
345 355
                event.preventDefault();
346
                var title = $('input#title').val();
347
348
                var form = $('form#new-directory');
349
                form.attr('action', form.attr('action') + title);
350
                form.submit();
351
356
                $('form#new-directory').submit();
352 357
                return false;
353 358
            });
354 359