Skip to content

Commit

Permalink
Fix xml parsing of open_search.xml (hound-search#267)
Browse files Browse the repository at this point in the history
open_search.xml file was being served using html/template package and since it doesn't know about xml contexts, it changes the first character of xml template "<" into "&lt;".

Now, we use two different packages:
- html/template - for parsing html template files
- text/template - for parsing text or xml template files

Closes hound-search#239
  • Loading branch information
sahildua2305 authored and stanistan committed Dec 21, 2017
1 parent bc1b3ac commit f73af2c
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 15 deletions.
21 changes: 18 additions & 3 deletions ui/content.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ui

import "html/template"
import "io"

// Current versions of some dependencies.
const (
Expand All @@ -10,6 +10,15 @@ const (

var contents map[string]*content

// This interface abstracts the Execute method on template which is
// structurally similar in both html/template and text/template.
// We need to use an interface instead of a direct template field
// because then we will need two different fields for html template
// and text template.
type renderer interface {
Execute(w io.Writer, data interface{}) error
}

type content struct {

// The uri for accessing this asset
Expand All @@ -21,8 +30,11 @@ type content struct {
// The JavaScript sources used in this HTML page
sources []string

// This is only created in prd-mode, the pre-parsed template
tpl *template.Template
// The parsed template - can be of html/template or text/template type
tpl renderer

// This is used to determine if a template is to be parsed as text or html
tplType string
}

func init() {
Expand All @@ -36,10 +48,12 @@ func init() {
"js/common.js",
"js/hound.js",
},
tplType: "html",
},

"/open_search.xml": &content{
template: "open_search.tpl.xml",
tplType: "xml",
},

"/excluded_files.html": &content{
Expand All @@ -48,6 +62,7 @@ func init() {
"js/common.js",
"js/excluded_files.js",
},
tplType: "html",
},
}
}
55 changes: 43 additions & 12 deletions ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package ui

import (
"bytes"
"errors"
"fmt"
"html/template"
html_template "html/template"
text_template "text/template"
"io"
"log"
"net/http"
Expand Down Expand Up @@ -61,10 +63,25 @@ func (h *devHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Renders a templated asset in dev-mode. This simply embeds external script tags
// for the source elements.
func renderForDev(w io.Writer, root string, c *content, cfg *config.Config, r *http.Request) error {
t, err := template.ParseFiles(
filepath.Join(root, c.template))
if err != nil {
return err
var err error
// For more context, see: https://github.com/etsy/hound/issues/239
switch c.tplType {
case "html":
// Use html/template to parse the html template
c.tpl, err = html_template.ParseFiles(filepath.Join(root, c.template))
if err != nil {
return err
}
case "xml", "text":
// Use text/template to parse the xml or text templates
// We are using text/template here for parsing xml to keep things
// consistent with html/template parsing.
c.tpl, err = text_template.ParseFiles(filepath.Join(root, c.template))
if err != nil {
return err
}
default:
return errors.New("invalid tplType for content")
}

json, err := cfg.ToJsonString()
Expand All @@ -84,11 +101,11 @@ func renderForDev(w io.Writer, root string, c *content, cfg *config.Config, r *h
path)
}

return t.Execute(w, map[string]interface{}{
return c.tpl.Execute(w, map[string]interface{}{
"ReactVersion": ReactVersion,
"jQueryVersion": JQueryVersion,
"ReposAsJson": json,
"Source": template.HTML(buf.String()),
"Source": html_template.HTML(buf.String()),
"Host": r.Host,
})
}
Expand Down Expand Up @@ -133,7 +150,6 @@ func (h *prdHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Renders a templated asset in prd-mode. This strategy will embed
// the sources directly in a script tag on the templated page.
func renderForPrd(w io.Writer, c *content, cfgJson string, r *http.Request) error {

var buf bytes.Buffer
buf.WriteString("<script>")
for _, src := range c.sources {
Expand All @@ -149,7 +165,7 @@ func renderForPrd(w io.Writer, c *content, cfgJson string, r *http.Request) erro
"ReactVersion": ReactVersion,
"jQueryVersion": JQueryVersion,
"ReposAsJson": cfgJson,
"Source": template.HTML(buf.String()),
"Source": html_template.HTML(buf.String()),
"Host": r.Host,
})
}
Expand Down Expand Up @@ -185,9 +201,24 @@ func newPrdHandler(cfg *config.Config) (http.Handler, error) {
return nil, err
}

cnt.tpl, err = template.New(cnt.template).Parse(string(a))
if err != nil {
return nil, err
// For more context, see: https://github.com/etsy/hound/issues/239
switch cnt.tplType {
case "html":
// Use html/template to parse the html template
cnt.tpl, err = html_template.New(cnt.template).Parse(string(a))
if err != nil {
return nil, err
}
case "xml", "text":
// Use text/template to parse the xml or text templates
// We are using text/template here for parsing xml to keep things
// consistent with html/template parsing.
cnt.tpl, err = text_template.New(cnt.template).Parse(string(a))
if err != nil {
return nil, err
}
default:
return nil, errors.New("invalid tplType for content")
}
}

Expand Down

0 comments on commit f73af2c

Please sign in to comment.