diff --git a/changelog.d/40.feature b/changelog.d/40.feature new file mode 100644 index 0000000..f472465 --- /dev/null +++ b/changelog.d/40.feature @@ -0,0 +1 @@ +Support element-android submitting logs with .gz suffix. diff --git a/submit.go b/submit.go index e53db1b..0554a4f 100644 --- a/submit.go +++ b/submit.go @@ -424,7 +424,7 @@ func saveFormPart(leafName string, reader io.Reader, reportDir string) (string, // we require a sensible extension, and don't allow the filename to start with // '.' -var logRegexp = regexp.MustCompile(`^[a-zA-Z0-9_-][a-zA-Z0-9_.-]*\.(log|txt)$`) +var logRegexp = regexp.MustCompile(`^[a-zA-Z0-9_-][a-zA-Z0-9_.-]*\.(log|txt)(\.gz)?$`) // saveLogPart saves a log upload to the report directory. // @@ -435,10 +435,16 @@ func saveLogPart(logNum int, filename string, reader io.Reader, reportDir string // some clients use sensible names (foo.N.log), which we preserve. For // others, we just make up a filename. // - // Either way, we need to append .gz, because we're compressing it. + // We append a ".gz" extension if not already present, as the final file we store on + // disk will be gzipped. The original filename may or may not contain a '.gz' depending + // on the client that uploaded it, and if it was uploaded already compressed. + var leafName string if logRegexp.MatchString(filename) { - leafName = filename + ".gz" + leafName = filename + if !strings.HasSuffix(filename, ".gz") { + leafName += ".gz" + } } else { leafName = fmt.Sprintf("logs-%04d.log.gz", logNum) } diff --git a/submit_test.go b/submit_test.go index f5cca86..e19be5f 100644 --- a/submit_test.go +++ b/submit_test.go @@ -160,6 +160,7 @@ func TestMultipartUpload(t *testing.T) { // check file uploaded correctly checkUploadedFile(t, reportDir, "passwd.txt", false, "bibblybobbly") + checkUploadedFile(t, reportDir, "crash.log.gz", true, "test\n") } func multipartBody() (body string) { @@ -215,6 +216,18 @@ Content-Type: application/octet-stream bibblybobbly ` + body += `------WebKitFormBoundarySsdgl8Nq9voFyhdO +Content-Disposition: form-data; name="compressed-log"; filename="crash.log.gz" +Content-Type: application/octet-stream + +` + body += string([]byte{ + 0x1f, 0x8b, 0x08, 0x00, 0xbf, 0xd8, 0xf5, 0x58, 0x00, 0x03, + 0x2b, 0x49, 0x2d, 0x2e, 0xe1, 0x02, 0x00, + 0xc6, 0x35, 0xb9, 0x3b, 0x05, 0x00, 0x00, 0x00, + 0x0a, + }) + body += "------WebKitFormBoundarySsdgl8Nq9voFyhdO--\n" return } @@ -224,8 +237,8 @@ func checkParsedMultipartUpload(t *testing.T, p *parsedPayload) { if p.UserText != wanted { t.Errorf("User text: got %s, want %s", p.UserText, wanted) } - if len(p.Logs) != 3 { - t.Errorf("Log length: got %d, want 3", len(p.Logs)) + if len(p.Logs) != 4 { + t.Errorf("Log length: got %d, want 4", len(p.Logs)) } if len(p.Data) != 3 { t.Errorf("Data length: got %d, want 3", len(p.Data)) @@ -249,6 +262,10 @@ func checkParsedMultipartUpload(t *testing.T, p *parsedPayload) { if p.Logs[2] != wanted { t.Errorf("Log 2: got %s, want %s", p.Logs[2], wanted) } + wanted = "crash.log.gz" + if p.Logs[3] != wanted { + t.Errorf("Log 3: got %s, want %s", p.Logs[3], wanted) + } } func TestLabels(t *testing.T) {