Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 67afddf

Browse files
committedOct 27, 2023
Force Content-Length HTTP header in import responses.
Previously, the Content-Length was missing and there was: Transfer-Encoding: chunked
1 parent 3fb1d55 commit 67afddf

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed
 

‎src/main/kotlin/fi/hsl/jore4/hastus/api/ImportController.kt

+24-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package fi.hsl.jore4.hastus.api
22

3+
import com.fasterxml.jackson.databind.ObjectMapper
34
import fi.hsl.jore4.hastus.Constants.MIME_TYPE_CSV
45
import fi.hsl.jore4.hastus.service.importing.ImportService
56
import mu.KotlinLogging
6-
import org.springframework.http.HttpStatus
7+
import org.springframework.http.HttpHeaders
8+
import org.springframework.http.MediaType
79
import org.springframework.http.ResponseEntity
810
import org.springframework.web.bind.annotation.ExceptionHandler
911
import org.springframework.web.bind.annotation.PostMapping
@@ -12,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestHeader
1214
import org.springframework.web.bind.annotation.RequestMapping
1315
import org.springframework.web.bind.annotation.RestController
1416
import org.springframework.web.server.ResponseStatusException
17+
import java.io.Serializable
1518
import java.util.UUID
1619
import kotlin.time.ExperimentalTime
1720
import kotlin.time.measureTimedValue
@@ -22,22 +25,23 @@ private val LOGGER = KotlinLogging.logger {}
2225
@RestController
2326
@RequestMapping("import")
2427
class ImportController(
25-
private val importService: ImportService
28+
private val importService: ImportService,
29+
private val objectMapper: ObjectMapper
2630
) {
2731

2832
data class ImportTimetablesSuccessResult(
2933
val vehicleScheduleFrameId: UUID?
30-
)
34+
) : Serializable
3135

3236
data class ImportTimetablesFailureResult(
3337
val reason: String?
34-
)
38+
) : Serializable
3539

3640
@PostMapping("", consumes = [MIME_TYPE_CSV])
3741
fun importCsvFile(
3842
@RequestBody csv: String,
3943
@RequestHeader headers: Map<String, String>
40-
): ImportTimetablesSuccessResult {
44+
): ResponseEntity<String> {
4145
val (nullableVehicleScheduleFrameId, elapsed) = measureTimedValue {
4246
LOGGER.info("Starting to import timetables from CSV file...")
4347

@@ -55,26 +59,36 @@ class ImportController(
5559

5660
LOGGER.info { "CSV import processing completed in $elapsed" }
5761

58-
return ImportTimetablesSuccessResult(nullableVehicleScheduleFrameId)
62+
return ResponseEntity.ok()
63+
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
64+
.body(
65+
serialise(
66+
ImportTimetablesSuccessResult(nullableVehicleScheduleFrameId)
67+
)
68+
)
5969
}
6070

6171
@ExceptionHandler
62-
fun handleExportException(ex: Exception): ResponseEntity<ImportTimetablesFailureResult> {
72+
fun handleExportException(ex: Exception): ResponseEntity<String> {
6373
return when (ex) {
6474
is ResponseStatusException -> {
6575
ResponseEntity
6676
.status(ex.statusCode)
67-
.body(ImportTimetablesFailureResult(ex.reason))
77+
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
78+
.body(serialise(ImportTimetablesFailureResult(ex.reason)))
6879
}
6980

7081
else -> {
7182
LOGGER.error { "Exception during import request:$ex" }
7283
LOGGER.error(ex.stackTraceToString())
7384

7485
ResponseEntity
75-
.status(HttpStatus.INTERNAL_SERVER_ERROR)
76-
.body(ImportTimetablesFailureResult(ex.message))
86+
.internalServerError()
87+
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
88+
.body(serialise(ImportTimetablesFailureResult(ex.message)))
7789
}
7890
}
7991
}
92+
93+
private fun serialise(obj: Serializable): String = objectMapper.writeValueAsString(obj)
8094
}

‎src/test/kotlin/fi/hsl/jore4/hastus/api/ImportControllerTest.kt

+6-6
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class ImportControllerTest @Autowired constructor(
6868

6969
executeImportTimetablesRequest("<some_csv_content>")
7070
.andExpect(status().isOk)
71-
.andExpect(header().doesNotExist(HttpHeaders.CONTENT_LENGTH))
71+
.andExpect(header().exists(HttpHeaders.CONTENT_LENGTH))
7272
.andExpect(
7373
content().json(
7474
"""
@@ -95,7 +95,7 @@ class ImportControllerTest @Autowired constructor(
9595

9696
executeImportTimetablesRequest("<invalid_csv_content>")
9797
.andExpect(status().isBadRequest)
98-
.andExpect(header().doesNotExist(HttpHeaders.CONTENT_LENGTH))
98+
.andExpect(header().exists(HttpHeaders.CONTENT_LENGTH))
9999
.andExpect(
100100
constructExpectedErrorBody(resultErrorMessage)
101101
)
@@ -118,7 +118,7 @@ class ImportControllerTest @Autowired constructor(
118118

119119
executeImportTimetablesRequest("<csv_content>")
120120
.andExpect(status().isBadRequest)
121-
.andExpect(header().doesNotExist(HttpHeaders.CONTENT_LENGTH))
121+
.andExpect(header().exists(HttpHeaders.CONTENT_LENGTH))
122122
.andExpect(
123123
constructExpectedErrorBody(
124124
"Could not find journey pattern reference for Hastus trips with the following route " +
@@ -141,7 +141,7 @@ class ImportControllerTest @Autowired constructor(
141141

142142
executeImportTimetablesRequest("<csv_content>")
143143
.andExpect(status().isBadRequest)
144-
.andExpect(header().doesNotExist(HttpHeaders.CONTENT_LENGTH))
144+
.andExpect(header().exists(HttpHeaders.CONTENT_LENGTH))
145145
.andExpect(
146146
constructExpectedErrorBody(
147147
"No journey pattern reference was found whose stop points correspond to the Hastus trip: " +
@@ -164,7 +164,7 @@ class ImportControllerTest @Autowired constructor(
164164

165165
executeImportTimetablesRequest("<csv_content>")
166166
.andExpect(status().isForbidden)
167-
.andExpect(header().doesNotExist(HttpHeaders.CONTENT_LENGTH))
167+
.andExpect(header().exists(HttpHeaders.CONTENT_LENGTH))
168168
.andExpect(
169169
constructExpectedErrorBody(resultErrorMessage)
170170
)
@@ -184,7 +184,7 @@ class ImportControllerTest @Autowired constructor(
184184

185185
executeImportTimetablesRequest("<csv_content>")
186186
.andExpect(status().isInternalServerError)
187-
.andExpect(header().doesNotExist(HttpHeaders.CONTENT_LENGTH))
187+
.andExpect(header().exists(HttpHeaders.CONTENT_LENGTH))
188188
.andExpect(
189189
constructExpectedErrorBody(resultErrorMessage)
190190
)

0 commit comments

Comments
 (0)
Please sign in to comment.