Skip to content

Instantly share code, notes, and snippets.

@newlandsvalley
Created November 14, 2016 15:22
Show Gist options
  • Save newlandsvalley/945d278e0570254285f77d0e863e8059 to your computer and use it in GitHub Desktop.
Save newlandsvalley/945d278e0570254285f77d0e863e8059 to your computer and use it in GitHub Desktop.
Tunnel binary through http using elm 0.18
{
"version": "2.1.0",
"summary": "test tunneling binary files through http",
"repository": "https://github.com/newlandsvalley/foobar.git",
"license": "BSD3",
"source-directories": [
"src"
],
"exposed-modules": [ ],
"dependencies": {
"elm-lang/core": "5.0.0 <= v < 6.0.0",
"elm-lang/html": "2.0.0 <= v < 3.0.0",
"elm-lang/http": "1.0.0 <= v < 2.0.0"
},
"elm-version": "0.18.0 <= v < 0.19.0"
}
module TunnelBinary18 exposing (..)
import Html exposing (..)
import Html.Events exposing (onClick)
import Http exposing (..)
import List exposing (..)
import String exposing (..)
import Result exposing (Result)
import Char exposing (fromCode, toCode)
import Bitwise exposing (and)
main =
Html.program
{ init = init "test binary http 0.18", update = update, view = view, subscriptions = \_ -> Sub.none }
-- MODEL
type alias MidiRecording =
List Int
type alias Model =
{ recording : Result String MidiRecording
}
init : String -> ( Model, Cmd Msg )
init topic =
( { recording = Err "not started" }
, Cmd.none
)
-- UPDATE
type Msg
= NoOp
| Load String
| Midi (Result String MidiRecording)
| MidiBinaryString (Result Error String)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
MidiBinaryString result ->
update (Midi (makeRecording result)) model
Midi recording ->
( { recording = recording }, Cmd.none )
Load url ->
( model, loadMidi url )
{- load a MIDI file - attempt to tunnel binary as text -}
loadMidi : String -> Cmd Msg
loadMidi url =
let
accept =
Http.header "Accept" "text/plain; charset=x-user-defined"
contentType =
Http.header "Content-Type" "text/plain; charset=x-user-defined"
rquest : Request String
rquest =
request
{ method = "Get"
, headers =
[ accept, contentType ]
--, headers = []
, url = url
, body = emptyBody
, expect = expectString
, timeout = Nothing
, withCredentials = False
}
in
Http.send MidiBinaryString rquest
makeRecording : Result Error String -> Result String MidiRecording
makeRecording s =
case s of
Ok text ->
text |> normalise |> Ok
Err e ->
Err (toString e)
{- try to get back something like the original binary -}
normalise : String -> MidiRecording
normalise =
let
f =
toCode >> ((and) 0xFF)
in
String.toList >> List.map f
-- VIEW
viewParseResult : Result String MidiRecording -> String
viewParseResult mr =
case mr of
Ok res ->
"OK: " ++ (toString res)
Err errs ->
"Fail: " ++ (toString errs)
view : Model -> Html Msg
view model =
div []
[ button [ onClick (Load "chordsample.midi") ] [ text "load MIDI sample" ]
, div [] [ text ("parse result: " ++ (viewParseResult model.recording)) ]
]
@newlandsvalley
Copy link
Author

The fundamental problem here is that I require a means of telling http to perform a binary read of the file (which it then can transmit as if it were text). As far as I can see, the new elm-lang/http gives me absolutely no means of doing this, whereas the evancz/elm-http supported it. So, the already paltry support for binary data in elm gets even worse in 0.18.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment