mirror of
https://github.com/gotson/komga.git
synced 2025-12-18 22:43:42 +01:00
fix: encode filenames in UTF-8 when downloading (#941)
Co-authored-by: ahamilton <ahamilton@emissary.co.jp> Co-authored-by: Gauthier Roebroeck <gauthier.roebroeck@gmail.com>
This commit is contained in:
parent
115be0ab32
commit
cf98e69374
6 changed files with 88 additions and 3 deletions
|
|
@ -81,6 +81,7 @@ import org.springframework.web.server.ResponseStatusException
|
|||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.OutputStream
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.nio.file.NoSuchFileException
|
||||
import java.time.LocalDate
|
||||
import java.time.ZoneOffset
|
||||
|
|
@ -386,7 +387,7 @@ class BookController(
|
|||
.headers(
|
||||
HttpHeaders().apply {
|
||||
contentDisposition = ContentDisposition.builder("attachment")
|
||||
.filename(book.path.name)
|
||||
.filename(book.path.name, UTF_8)
|
||||
.build()
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ import org.springframework.web.multipart.MultipartFile
|
|||
import org.springframework.web.server.ResponseStatusException
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody
|
||||
import java.io.OutputStream
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.zip.Deflater
|
||||
import javax.validation.Valid
|
||||
|
|
@ -422,7 +423,7 @@ class ReadListController(
|
|||
.headers(
|
||||
HttpHeaders().apply {
|
||||
contentDisposition = ContentDisposition.builder("attachment")
|
||||
.filename(readList.name + ".zip")
|
||||
.filename(readList.name + ".zip", UTF_8)
|
||||
.build()
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ import org.springframework.web.multipart.MultipartFile
|
|||
import org.springframework.web.server.ResponseStatusException
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody
|
||||
import java.io.OutputStream
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
import java.util.zip.Deflater
|
||||
import javax.validation.Valid
|
||||
|
||||
|
|
@ -672,7 +673,7 @@ class SeriesController(
|
|||
.headers(
|
||||
HttpHeaders().apply {
|
||||
contentDisposition = ContentDisposition.builder("attachment")
|
||||
.filename(seriesMetadataRepository.findById(seriesId).title + ".zip")
|
||||
.filename(seriesMetadataRepository.findById(seriesId).title + ".zip", UTF_8)
|
||||
.build()
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.gotson.komga.domain.service.LibraryLifecycle
|
|||
import org.gotson.komga.domain.service.SeriesLifecycle
|
||||
import org.gotson.komga.infrastructure.security.KomgaPrincipal
|
||||
import org.hamcrest.Matchers
|
||||
import org.hamcrest.Matchers.containsString
|
||||
import org.hamcrest.core.IsNull
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
|
|
@ -49,6 +50,9 @@ import org.springframework.test.web.servlet.get
|
|||
import org.springframework.test.web.servlet.patch
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Files
|
||||
import java.time.LocalDate
|
||||
import kotlin.random.Random
|
||||
|
||||
|
|
@ -1346,4 +1350,26 @@ class BookControllerTest(
|
|||
jsonPath("$.totalElements").value(2),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockCustomUser
|
||||
fun `given book with Unicode name when getting book file then attachment name is correct`() {
|
||||
val bookName = "アキラ"
|
||||
val tempFile = Files.createTempFile(bookName, ".cbz")
|
||||
.also { it.toFile().deleteOnExit() }
|
||||
makeSeries(name = "series", libraryId = library.id).let { series ->
|
||||
seriesLifecycle.createSeries(series).let { created ->
|
||||
val books = listOf(makeBook(bookName, libraryId = library.id, url = tempFile.toUri().toURL()))
|
||||
seriesLifecycle.addBooks(created, books)
|
||||
}
|
||||
}
|
||||
|
||||
val book = bookRepository.findAll().first()
|
||||
|
||||
mockMvc.get("/api/v1/books/${book.id}/file")
|
||||
.andExpect {
|
||||
status { isOk() }
|
||||
header { string("Content-Disposition", containsString(URLEncoder.encode(bookName, StandardCharsets.UTF_8.name()))) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import org.gotson.komga.domain.service.LibraryLifecycle
|
|||
import org.gotson.komga.domain.service.ReadListLifecycle
|
||||
import org.gotson.komga.domain.service.SeriesLifecycle
|
||||
import org.gotson.komga.language.toIndexedMap
|
||||
import org.hamcrest.Matchers
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
|
|
@ -29,6 +30,9 @@ import org.springframework.test.web.servlet.delete
|
|||
import org.springframework.test.web.servlet.get
|
||||
import org.springframework.test.web.servlet.patch
|
||||
import org.springframework.test.web.servlet.post
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Files
|
||||
|
||||
@ExtendWith(SpringExtension::class)
|
||||
@SpringBootTest
|
||||
|
|
@ -979,4 +983,32 @@ class ReadListControllerTest(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockCustomUser
|
||||
fun `given readlist with Unicode name when getting readlist file then attachment name is correct`() {
|
||||
val name = "アキラ"
|
||||
val tempFile = Files.createTempFile(name, ".cbz")
|
||||
.also { it.toFile().deleteOnExit() }
|
||||
val book = makeBook(name, libraryId = library1.id, url = tempFile.toUri().toURL())
|
||||
makeSeries(name = "series", libraryId = library1.id).let { series ->
|
||||
seriesLifecycle.createSeries(series).let { created ->
|
||||
val books = listOf(book)
|
||||
seriesLifecycle.addBooks(created, books)
|
||||
}
|
||||
}
|
||||
|
||||
val readlist = readListLifecycle.addReadList(
|
||||
ReadList(
|
||||
name = name,
|
||||
bookIds = listOf(book.id).toIndexedMap(),
|
||||
),
|
||||
)
|
||||
|
||||
mockMvc.get("/api/v1/readlists/${readlist.id}/file")
|
||||
.andExpect {
|
||||
status { isOk() }
|
||||
header { string("Content-Disposition", Matchers.containsString(URLEncoder.encode(name, StandardCharsets.UTF_8.name()))) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ import org.springframework.test.web.servlet.delete
|
|||
import org.springframework.test.web.servlet.get
|
||||
import org.springframework.test.web.servlet.patch
|
||||
import org.springframework.test.web.servlet.post
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Files
|
||||
import kotlin.random.Random
|
||||
|
||||
@ExtendWith(SpringExtension::class)
|
||||
|
|
@ -1075,4 +1078,25 @@ class SeriesControllerTest(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockCustomUser
|
||||
fun `given series with Unicode name when getting series file then attachment name is correct`() {
|
||||
val name = "アキラ"
|
||||
val tempFile = Files.createTempFile(name, ".cbz")
|
||||
.also { it.toFile().deleteOnExit() }
|
||||
val series = makeSeries(name = name, libraryId = library.id).let { series ->
|
||||
seriesLifecycle.createSeries(series).let { created ->
|
||||
val books = listOf(makeBook(name, libraryId = library.id, url = tempFile.toUri().toURL()))
|
||||
seriesLifecycle.addBooks(created, books)
|
||||
}
|
||||
series
|
||||
}
|
||||
|
||||
mockMvc.get("/api/v1/series/${series.id}/file")
|
||||
.andExpect {
|
||||
status { isOk() }
|
||||
header { string("Content-Disposition", Matchers.containsString(URLEncoder.encode(name, StandardCharsets.UTF_8.name()))) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue