aboutsummaryrefslogtreecommitdiff
path: root/src/util/http.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/http.ts')
-rw-r--r--src/util/http.ts109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/util/http.ts b/src/util/http.ts
new file mode 100644
index 000000000..a2bfab279
--- /dev/null
+++ b/src/util/http.ts
@@ -0,0 +1,109 @@
+/*
+ This file is part of TALER
+ (C) 2016 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Helpers for doing XMLHttpRequest-s that are based on ES6 promises.
+ * Allows for easy mocking for test cases.
+ */
+
+/**
+ * An HTTP response that is returned by all request methods of this library.
+ */
+export interface HttpResponse {
+ status: number;
+ responseJson: object & any;
+}
+
+/**
+ * The request library is bundled into an interface to make mocking easy.
+ */
+export interface HttpRequestLibrary {
+ get(url: string): Promise<HttpResponse>;
+
+ postJson(url: string, body: any): Promise<HttpResponse>;
+}
+
+/**
+ * An implementation of the [[HttpRequestLibrary]] using the
+ * browser's XMLHttpRequest.
+ */
+export class BrowserHttpLib implements HttpRequestLibrary {
+ private req(
+ method: string,
+ url: string,
+ options?: any,
+ ): Promise<HttpResponse> {
+ return new Promise<HttpResponse>((resolve, reject) => {
+ const myRequest = new XMLHttpRequest();
+ myRequest.open(method, url);
+ if (options && options.req) {
+ myRequest.send(options.req);
+ } else {
+ myRequest.send();
+ }
+
+ myRequest.onerror = e => {
+ console.error("http request error");
+ reject(Error("could not make XMLHttpRequest"));
+ };
+
+ myRequest.addEventListener("readystatechange", e => {
+ if (myRequest.readyState === XMLHttpRequest.DONE) {
+ if (myRequest.status === 0) {
+ reject(Error("HTTP Request failed (status code 0, maybe URI scheme is wrong?)"))
+ return;
+ }
+ if (myRequest.status != 200) {
+ reject(
+ Error(
+ `HTTP Response with unexpected status code ${myRequest.status}: ${myRequest.statusText}`,
+ ),
+ );
+ return;
+ }
+ let responseJson;
+ try {
+ responseJson = JSON.parse(myRequest.responseText);
+ } catch (e) {
+ reject(Error("Invalid JSON from HTTP response"));
+ return;
+ }
+ if (responseJson === null || typeof responseJson !== "object") {
+ reject(Error("Invalid JSON from HTTP response"));
+ return;
+ }
+ const resp = {
+ responseJson: responseJson,
+ status: myRequest.status,
+ };
+ resolve(resp);
+ }
+ });
+ });
+ }
+
+ get(url: string) {
+ return this.req("get", url);
+ }
+
+ postJson(url: string, body: any) {
+ return this.req("post", url, { req: JSON.stringify(body) });
+ }
+
+ postForm(url: string, form: any) {
+ return this.req("post", url, { req: form });
+ }
+}