http-directory (empty) → 0.1.0
raw patch · 6 files changed
+163/−0 lines, 6 filesdep +basedep +bytestringdep +html-conduitsetup-changed
Dependencies added: base, bytestring, html-conduit, http-client, http-types, semigroups, text, xml-conduit
Files
- CHANGELOG.md +6/−0
- LICENSE +21/−0
- README.md +9/−0
- Setup.hs +2/−0
- http-directory.cabal +45/−0
- src/Network/HTTP/Directory.hs +80/−0
+ CHANGELOG.md view
@@ -0,0 +1,6 @@+# Changelog++`http-directory` uses [PVP Versioning](https://pvp.haskell.org).++## 0.1.0+- initial release with httpDirectory, httpFileSize, and httpRedirect(s)
+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2019 Jens Petersen++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ README.md view
@@ -0,0 +1,9 @@+# http-directory++[](https://hackage.haskell.org/package/http-directory)+[](LICENSE)+[](http://stackage.org/lts/package/http-directory)+[](http://stackage.org/nightly/package/http-directory)+[](https://travis-ci.org/juhp/http-directory)++A simple library for reading http directories.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ http-directory.cabal view
@@ -0,0 +1,45 @@+cabal-version: 1.18+name: http-directory+version: 0.1.0+synopsis: http directory listing library+description:+ Library for listing http directories of files (links).+ Also it can check the size of files, and url redirects.+homepage: https://github.com/juhp/http-directory+bug-reports: https://github.com/juhp/http-directory/issues+license: MIT+license-file: LICENSE+author: Jens Petersen+maintainer: juhpetersen@gmail.com+copyright: 2019 Jens Petersen+category: Network+build-type: Simple+extra-doc-files: README.md+ , CHANGELOG.md+tested-with: GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2,+ GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.4++source-repository head+ type: git+ location: https://github.com/juhp/http-directory.git++library+ hs-source-dirs: src+ exposed-modules: Network.HTTP.Directory+ ++ build-depends: base < 5,+ bytestring,+ html-conduit,+ http-client,+ http-types,+ text,+ xml-conduit+ if impl(ghc<8.0)+ Build-depends: semigroups++ ghc-options: -fwarn-missing-signatures+ -Wall++ default-language: Haskell2010+ default-extensions: OverloadedStrings
+ src/Network/HTTP/Directory.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE CPP #-}++{-|+A library for listing "files" in an http "directory".++@+import Network.HTTP.Directory+import qualified Data.Text as T++main = do+ files <- httpDirectory "https://example.com/some/dir/"+ mapM_ T.putStrLn files+ httpFileSize (head files) >>= print+@+-}++module Network.HTTP.Directory+ ( httpDirectory,+ httpFileSize,+ httpRedirect,+ httpRedirects+ ) where++#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))+#else+import Control.Applicative ((<$>))+#endif++import qualified Data.ByteString.Char8 as B+import Data.Maybe+import Data.Text (Text)++import Network.HTTP.Client (hrRedirects, httpLbs, httpNoBody, Manager, method,+ parseRequest, responseBody, responseHeaders,+ responseOpenHistory, responseStatus)+import Network.HTTP.Types (hContentLength, hLocation, statusCode)++import Text.HTML.DOM (parseLBS)+import Text.XML.Cursor++-- | List the file links (hrefs) in an http directory+--+-- Note if the directory (webpage) url is redirected you may need to use+-- 'httpRedirect' to determine the actual final url prefix for relative links+-- (files).+httpDirectory :: Manager -> String -> IO [Text]+httpDirectory mgr url = do+ request <- parseRequest url+ response <- httpLbs request mgr+ if statusCode (responseStatus response) /= 200+ then error $ show $ responseStatus response+ else do+ let body = responseBody response+ doc = parseLBS body+ cursor = fromDocument doc+ return $ concatMap (attribute "href") $ cursor $// element "a"++-- | Try to get the filesize (Content-Length) of an http file+httpFileSize :: Manager -> String -> IO (Maybe Integer)+httpFileSize mgr url = do+ request <- parseRequest url+ response <- httpNoBody (request {method = "HEAD"}) mgr+ if statusCode (responseStatus response) /= 200+ then error $ show $ responseStatus response+ else do+ let headers = responseHeaders response+ return $ read . B.unpack <$> lookup hContentLength headers++-- | Returns the list of http redirects for an url in reverse order+-- (ie last redirect is first)+httpRedirects :: Manager -> String -> IO [B.ByteString]+httpRedirects mgr url = do+ request <- parseRequest url+ respHist <- responseOpenHistory (request {method = "HEAD"}) mgr+ return $ reverse $ mapMaybe (lookup hLocation . responseHeaders . snd) $ hrRedirects respHist++-- | Return final redirect for an url+httpRedirect :: Manager -> String -> IO (Maybe B.ByteString)+httpRedirect mgr url =+ listToMaybe <$> httpRedirects mgr url