Skip to content

Commit

Permalink
Merge pull request #3548 from ashwinbhaskar/read_directory_fix_series_21
Browse files Browse the repository at this point in the history
Read directory fix series 21
  • Loading branch information
rossabaker committed Jun 30, 2020
2 parents 1598283 + 6c3558c commit 27d70d4
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 23 deletions.
54 changes: 31 additions & 23 deletions core/src/main/scala/org/http4s/StaticFile.scala
Expand Up @@ -66,31 +66,39 @@ object StaticFile {

def fromURL[F[_]](url: URL, blocker: Blocker, req: Option[Request[F]] = None)(implicit
F: Sync[F],
cs: ContextShift[F]): OptionT[F, Response[F]] =
OptionT.liftF(F.delay {
val urlConn = url.openConnection
val lastmod = HttpDate.fromEpochSecond(urlConn.getLastModified / 1000).toOption
val ifModifiedSince = req.flatMap(_.headers.get(`If-Modified-Since`))
val expired = (ifModifiedSince, lastmod).mapN(_.date < _).getOrElse(true)

if (expired) {
val lastModHeader: List[Header] = lastmod.map(`Last-Modified`(_)).toList
val contentType = nameToContentType(url.getPath).toList
val len = urlConn.getContentLengthLong
val lenHeader =
if (len >= 0) `Content-Length`.unsafeFromLong(len)
else `Transfer-Encoding`(TransferCoding.chunked)
val headers = Headers(lenHeader :: lastModHeader ::: contentType)

Response(
headers = headers,
body = readInputStream[F](F.delay(url.openStream), DefaultBufferSize, blocker)
)
} else {
urlConn.getInputStream.close()
Response(NotModified)
cs: ContextShift[F]): OptionT[F, Response[F]] = {
val fileUrl = url.getFile()
val file = new File(fileUrl)
OptionT.apply(F.delay {
if (file.isDirectory())
None
else {
val urlConn = url.openConnection
val lastmod = HttpDate.fromEpochSecond(urlConn.getLastModified / 1000).toOption
val ifModifiedSince = req.flatMap(_.headers.get(`If-Modified-Since`))
val expired = (ifModifiedSince, lastmod).mapN(_.date < _).getOrElse(true)

if (expired) {
val lastModHeader: List[Header] = lastmod.map(`Last-Modified`(_)).toList
val contentType = nameToContentType(url.getPath).toList
val len = urlConn.getContentLengthLong
val lenHeader =
if (len >= 0) `Content-Length`.unsafeFromLong(len)
else `Transfer-Encoding`(TransferCoding.chunked)
val headers = Headers(lenHeader :: lastModHeader ::: contentType)

Some(
Response(
headers = headers,
body = readInputStream[F](F.delay(url.openStream), DefaultBufferSize, blocker)
))
} else {
urlConn.getInputStream.close()
Some(Response(NotModified))
}
}
})
}

def calcETag[F[_]: Sync]: File => F[String] =
f =>
Expand Down
Empty file.
9 changes: 9 additions & 0 deletions tests/src/test/scala/org/http4s/StaticFileSpec.scala
Expand Up @@ -276,5 +276,14 @@ class StaticFileSpec extends Http4sSpec with Http4sLegacyMatchersIO {
.map(_.flatMap(_.contentLength))
len must returnValue(Some(24005L))
}

"return none from a URL that is a directory" in {
// val url = getClass.getResource("/foo")
val s = StaticFile
.fromURL[IO](getClass.getResource("/foo"), testBlocker)
.value
.unsafeRunSync
s must_== None
}
}
}

0 comments on commit 27d70d4

Please sign in to comment.