Skip to content
Permalink
Browse files

Update to an API that supports bytes and files

  • Loading branch information...
evancz committed Oct 26, 2018
1 parent 440187b commit 5add5278999a5778fc729a06564b88ef8442f2f9
Showing with 821 additions and 483 deletions.
  1. +3 −1 elm.json
  2. +79 −105 src/Elm/Kernel/Http.js
  3. +17 −16 src/Elm/Kernel/Http.server.js
  4. +368 −160 src/Http.elm
  5. +354 −0 src/Http/Advanced.elm
  6. +0 −201 src/Http/Progress.elm
@@ -6,11 +6,13 @@
"version": "1.0.0",
"exposed-modules": [
"Http",
"Http.Progress"
"Http.Advanced"
],
"elm-version": "0.19.0 <= v < 0.20.0",
"dependencies": {
"elm/bytes": "1.0.0 <= v < 2.0.0",
"elm/core": "1.0.0 <= v < 2.0.0",
"elm/file": "1.0.0 <= v < 2.0.0",
"elm/json": "1.0.0 <= v < 2.0.0"
},
"test-dependencies": {}
@@ -2,137 +2,107 @@
import Dict exposing (empty, update)
import Elm.Kernel.Scheduler exposing (binding, fail, rawSpawn, succeed)
import Http exposing (BadUrl, Timeout, NetworkError, BadStatus, BadPayload)
import Http.Internal as HI exposing (FormDataBody, isStringBody)
import Maybe exposing (Just, isJust)
import Elm.Kernel.Utils exposing (Tuple2)
import Http.Advanced as Http exposing (BadUrl, Timeout, NetworkError, BadStatus, GoodStatus, Sending, Receiving)
import Maybe exposing (Just, Nothing, isJust)
import Platform exposing (sendToApp, sendToSelf)
import Result exposing (map, isOk)
*/


// COERCE

function _Http_coerce(x) { return x; }


// SEND REQUEST

var _Http_toTask = F2(function(request, maybeProgress)
var _Http_toTask = F3(function(router, toMsg, request)
{
return __Scheduler_binding(function(callback)
{
var xhr = new XMLHttpRequest();

_Http_configureProgress(xhr, maybeProgress);
function done(response) {
callback(A2(__Platform_sendToApp, router, toMsg(request.__$expect.b(response))));
}

xhr.addEventListener('error', function() {
callback(__Scheduler_fail(__Http_NetworkError));
});
xhr.addEventListener('timeout', function() {
callback(__Scheduler_fail(__Http_Timeout));
});
xhr.addEventListener('load', function() {
callback(_Http_handleResponse(xhr, request.__$expect.__responseToResult));
});
var xhr = new XMLHttpRequest();
xhr.addEventListener('error', function() { done(__Http_NetworkError); });
xhr.addEventListener('timeout', function() { done(__Http_Timeout); });
xhr.addEventListener('load', function() { done(_Http_toResponse(xhr)); });
__Maybe_isJust(request.__$tracker) && _Http_track(router, xhr, request.__$tracker.a);

try
{
try {
xhr.open(request.__$method, request.__$url, true);
}
catch (e)
{
return callback(__Scheduler_fail(__Http_BadUrl(request.__$url)));
} catch (e) {
return done(__Http_BadUrl(request.__$url));
}

_Http_configureRequest(xhr, request);

var body = request.__$body;
xhr.send(__HI_isStringBody(body)
? (xhr.setRequestHeader('Content-Type', body.a), body.b)
: body.a
);
request.__$body.a && xhr.setRequestHeader('Content-Type', request.__$body.a);
xhr.send(request.__$body.b);

return function() { xhr.abort(); };
});
});

function _Http_configureProgress(xhr, maybeProgress)
{
if (!__Maybe_isJust(maybeProgress))
{
return;
}

xhr.addEventListener('progress', function(event) {
if (!event.lengthComputable)
{
return;
}
__Scheduler_rawSpawn(maybeProgress.a({
__$bytes: event.loaded,
__$bytesExpected: event.total
}));
});
}
// CONFIGURE

function _Http_configureRequest(xhr, request)
{
for (var headers = request.__$headers; headers.b; headers = headers.b) // WHILE_CONS
{
xhr.setRequestHeader(headers.a.a, headers.a.b);
}

xhr.responseType = request.__$expect.__responseType;
xhr.withCredentials = request.__$withCredentials;

__Maybe_isJust(request.__$timeout) && (xhr.timeout = request.__$timeout.a);
xhr.timeout = request.__$timeout.a || 0;
xhr.responseType = request.__$expect.a;
xhr.withCredentials = request.__$allowCookiesFromOtherDomains;
}


// RESPONSES

function _Http_handleResponse(xhr, responseToResult)
function _Http_toResponse(xhr)
{
var response = _Http_toResponse(xhr);

if (xhr.status < 200 || 300 <= xhr.status)
{
response.body = xhr.responseText;
return __Scheduler_fail(__Http_BadStatus(response));
}
console.log(typeof xhr.response); // TODO new DataView()
return A2(
200 <= xhr.status && xhr.status < 300 ? __Http_GoodStatus : __Http_BadStatus,
_Http_toMetadata(xhr),
xhr.response
);
}

var result = responseToResult(response);

if (__Result_isOk(result))
{
return __Scheduler_succeed(result.a);
}
else
{
response.body = xhr.responseText;
return __Scheduler_fail(A2(__Http_BadPayload, result.a, response));
}
}
// METADATA

function _Http_toResponse(xhr)
function _Http_toMetadata(xhr)
{
return {
__$url: xhr.responseURL,
__$status: { __$code: xhr.status, __$message: xhr.statusText },
__$headers: _Http_parseHeaders(xhr.getAllResponseHeaders()),
__$body: xhr.response
__$statusCode: xhr.status,
__$statusText: xhr.statusText,
__$headers: _Http_parseHeaders(xhr.getAllResponseHeaders())
};
}


// HEADERS

function _Http_parseHeaders(rawHeaders)
{
var headers = __Dict_empty;

if (!rawHeaders)
{
return headers;
return __Dict_empty;
}

var headerPairs = rawHeaders.split('\u000d\u000a');
var headers = __Dict_empty;
var headerPairs = rawHeaders.split('\r\n');
for (var i = headerPairs.length; i--; )
{
var headerPair = headerPairs[i];
var index = headerPair.indexOf('\u003a\u0020');
var index = headerPair.indexOf(': ');
if (index > 0)
{
var key = headerPair.substring(0, index);
@@ -146,46 +116,50 @@ function _Http_parseHeaders(rawHeaders)
}, headers);
}
}

return headers;
}


// EXPECTORS
// PAIR

function _Http_expectStringResponse(responseToResult)
{
return {
$: __0_EXPECT,
__responseType: 'text',
__responseToResult: responseToResult
};
}

var _Http_mapExpect = F2(function(func, expect)
{
return {
$: __0_EXPECT,
__responseType: expect.__responseType,
__responseToResult: function(response) {
var convertedResponse = expect.__responseToResult(response);
return A2(__Result_map, func, convertedResponse);
}
};
});
var _Http_pair = F2(function(a, b) { return { $: 0, a: a, b: b }; });
var _Http_emptyBody = { $: 0 };


// BODY
// BODY PARTS

function _Http_multipart(parts)
function _Http_toFormData(parts)
{


for (var formData = new FormData(); parts.b; parts = parts.b) // WHILE_CONS
{
var part = parts.a;
formData.append(part.a, part.b);
}

return __HI_FormDataBody(formData);
return formData;
}

var _Http_bytesToBlob = F2(function(mime, bytes)
{
return new Blob([bytes], { type: mime });
});


// PROGRESS

function _Http_track(router, xhr, tracker)
{
// TODO check out lengthComputable on loadstart event

xhr.upload.addEventListener('progress', function(event) {
__Scheduler_rawSpawn(A2(__Platform_sendToSelf, router, __Utils_Tuple2(tracker, __Http_Sending({
__$sent: event.loaded,
__$size: event.total
}))));
});
xhr.addEventListener('progress', function(event) {
__Scheduler_rawSpawn(A2(__Platform_sendToSelf, router, __Utils_Tuple2(tracker, __Http_Receiving({
__$received: event.loaded,
__$size: event.lengthComputable ? __Maybe_Just(event.total) : __Maybe_Nothing
}))));
});
}
@@ -2,12 +2,11 @@
import Elm.Kernel.Platform exposing (preload)
import Elm.Kernel.Scheduler exposing (binding)
import Http.Internal as HI exposing (FormDataBody)
*/


var _Http_toTask = F2(function(request, maybeProgress)
var _Http_toTask = F3(function(router, toMsg, request)
{
return __Scheduler_binding(function(callback)
{
@@ -16,24 +15,26 @@ var _Http_toTask = F2(function(request, maybeProgress)
});


function _Http_expectStringResponse(responseToResult)
{
return {
$: __0_EXPECT,
__responseType: 'text',
__responseToResult: responseToResult
};
}
// PAIR

var _Http_pair = F2(function(a, b) { return { $: 0, a: a, b: b }; });
var _Http_emptyBody = { $: 0 };
function _Http_coerce(x) { return x; }


// BODY PARTS

function _Http_multipart()
function _Http_toFormData(parts)
{
return __HI_FormDataBody(new FormData());
for (var formData = new FormData(); parts.b; parts = parts.b) // WHILE_CONS
{
var part = parts.a;
formData.append(part.a, part.b);
}
return formData;
}


var _Http_mapExpect = F2(function(func, expect)
var _Http_bytesToBlob = F2(function(mime, bytes)
{
return expect;
return new Blob([bytes], { type: mime });
});

0 comments on commit 5add527

Please sign in to comment.
You can’t perform that action at this time.