mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
Merge pull request #357 from tw4452852/my_md
markdown: fix json front matter parse issue when body content is long
This commit is contained in:
commit
ef2ca1da3d
1 changed files with 26 additions and 45 deletions
|
@ -1,11 +1,9 @@
|
||||||
package markdown
|
package markdown
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
@ -73,23 +71,20 @@ type JSONMetadataParser struct {
|
||||||
|
|
||||||
// Parse the metadata
|
// Parse the metadata
|
||||||
func (j *JSONMetadataParser) Parse(b []byte) ([]byte, error) {
|
func (j *JSONMetadataParser) Parse(b []byte) ([]byte, error) {
|
||||||
|
b, markdown, err := extractMetadata(j, b)
|
||||||
|
if err != nil {
|
||||||
|
return markdown, err
|
||||||
|
}
|
||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
|
|
||||||
// Read the preceding JSON object
|
// Read the preceding JSON object
|
||||||
decoder := json.NewDecoder(bytes.NewReader(b))
|
decoder := json.NewDecoder(bytes.NewReader(b))
|
||||||
if err := decoder.Decode(&m); err != nil {
|
if err := decoder.Decode(&m); err != nil {
|
||||||
return b, err
|
return markdown, err
|
||||||
}
|
}
|
||||||
j.metadata.load(m)
|
j.metadata.load(m)
|
||||||
|
|
||||||
// Retrieve remaining bytes after decoding
|
return markdown, nil
|
||||||
buf := make([]byte, len(b))
|
|
||||||
n, err := decoder.Buffered().Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
return b, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf[:n], nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metadata returns parsed metadata. It should be called
|
// Metadata returns parsed metadata. It should be called
|
||||||
|
@ -183,43 +178,29 @@ func (y *YAMLMetadataParser) Closing() []byte {
|
||||||
// It returns the metadata, the remaining bytes (markdown), and an error, if any.
|
// It returns the metadata, the remaining bytes (markdown), and an error, if any.
|
||||||
func extractMetadata(parser MetadataParser, b []byte) (metadata []byte, markdown []byte, err error) {
|
func extractMetadata(parser MetadataParser, b []byte) (metadata []byte, markdown []byte, err error) {
|
||||||
b = bytes.TrimSpace(b)
|
b = bytes.TrimSpace(b)
|
||||||
reader := bufio.NewReader(bytes.NewBuffer(b))
|
openingLine := append(parser.Opening(), '\n')
|
||||||
|
closingLine := append(parser.Closing(), '\n')
|
||||||
// Read first line, which should indicate metadata or not
|
if !bytes.HasPrefix(b, openingLine) {
|
||||||
line, err := reader.ReadBytes('\n')
|
|
||||||
if err != nil || !bytes.Equal(bytes.TrimSpace(line), parser.Opening()) {
|
|
||||||
return nil, b, fmt.Errorf("first line missing expected metadata identifier")
|
return nil, b, fmt.Errorf("first line missing expected metadata identifier")
|
||||||
}
|
}
|
||||||
|
metaStart := len(openingLine)
|
||||||
// buffer for metadata contents
|
if _, ok := parser.(*JSONMetadataParser); ok {
|
||||||
metaBuf := bytes.Buffer{}
|
metaStart = 0
|
||||||
|
|
||||||
// Read remaining lines until closing identifier is found
|
|
||||||
for {
|
|
||||||
line, err := reader.ReadBytes('\n')
|
|
||||||
if err != nil && err != io.EOF {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
}
|
||||||
|
metaEnd := bytes.Index(b[metaStart:], closingLine)
|
||||||
// if closing identifier found, the remaining bytes must be markdown content
|
if metaEnd == -1 {
|
||||||
if bytes.Equal(bytes.TrimSpace(line), parser.Closing()) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// if file ended, by this point no closing identifier was found
|
|
||||||
if err == io.EOF {
|
|
||||||
return nil, nil, fmt.Errorf("metadata not closed ('%s' not found)", parser.Closing())
|
return nil, nil, fmt.Errorf("metadata not closed ('%s' not found)", parser.Closing())
|
||||||
}
|
}
|
||||||
|
metaEnd += metaStart
|
||||||
metaBuf.Write(line)
|
if _, ok := parser.(*JSONMetadataParser); ok {
|
||||||
metaBuf.WriteString("\r\n")
|
metaEnd += len(closingLine)
|
||||||
}
|
}
|
||||||
|
metadata = b[metaStart:metaEnd]
|
||||||
// By now, the rest of the buffer contains markdown content
|
markdown = b[metaEnd:]
|
||||||
contentBuf := new(bytes.Buffer)
|
if _, ok := parser.(*JSONMetadataParser); !ok {
|
||||||
io.Copy(contentBuf, reader)
|
markdown = b[metaEnd+len(closingLine):]
|
||||||
|
}
|
||||||
return metaBuf.Bytes(), contentBuf.Bytes(), nil
|
return metadata, markdown, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// findParser finds the parser using line that contains opening identifier
|
// findParser finds the parser using line that contains opening identifier
|
||||||
|
|
Loading…
Reference in a new issue