Example #1
0
 const lookupResult: T.Task<P.Either<string, LookupResult>> = T.co(function* () {
   const nonIndexResult: LookupResult  = yield settings.lookupFile(pieces);
   if (nonIndexResult.tag === LookupResultType.LRFILE) {
     return T.pure(P.right(nonIndexResult));
   }
   const eIndexResult: P.Either<string, LookupResult> = yield lookupIndices(
     settings.indices.map(ix => dropLastIfNull(pieces.concat(ix)))
   );
   if (P.isLeft(eIndexResult)) {
     return T.pure(P.left(eIndexResult.value));
   }
   const { value: indexResult } = eIndexResult;
   if (indexResult.tag === LookupResultType.LRNOTFOUND) {
     return T.pure(P.right(nonIndexResult));
   }
   if (indexResult.tag === LookupResultType.LRFILE && settings.redirectToIndex) {
     const file = indexResult.file;
     return T.pure(P.left((function () {
       const repieces = pieces.slice().reverse();
       if (repieces.length === 0) {
         return file.name;
       }
       const lastSegment = repieces[0];
       if (lastSegment == '') return file.name;
       return `${lastSegment}/${file.name}`;
     })()));
   }
   return T.pure(P.right(indexResult));
 });
Example #2
0
function sendRsp(
  conn: Z.Connection,
  ii: Z.InternalInfo,
  status: H.Status,
  headers: H.ResponseHeaders,
  rsp: Rsp
): T.Task<[P.Maybe<H.Status>, P.Maybe<number>]> {
  switch (rsp.tag) {
    case RspType.RSPBUFFER:
      return conn.writeHead(status, headers)
        .chain(() => conn.sendAll(rsp.buffer))
        .then(T.pure([P.just(status), P.just(Buffer.byteLength(rsp.buffer))] as [P.Maybe<H.Status>, P.Maybe<number>]));

    case RspType.RSPREADABLE:
      return conn.writeHead(status, headers)
        .chain(_ => conn.sendStream(rsp.readable))
        .map(_ => [P.just(status), P.nothing] as [P.Maybe<H.Status>, P.Maybe<number>]);

    case RspType.RSPNOBODY:
      return conn.writeHead(status, headers)
        .then(T.pure([P.just(status), P.nothing] as [P.Maybe<H.Status>, P.Maybe<number>]));

    case RspType.RSPFILE:
      if (rsp.part != null) {
        const part = rsp.part;
        return sendRspFile2XX(conn, ii, status, addContentHeadersForFilePart(headers, part),
                              rsp.path, part.offset, part.byteCount, rsp.isHead);
      }
      return T.attempt(ii.getFinfo(rsp.path))
        .chain(efinfo => {
          if (P.isLeft(efinfo)) {
            return sendRspFile404(conn, ii, headers);
          }
          const rspFile = conditionalRequest(efinfo.value, headers, rsp.header);
          switch (rspFile.tag) {
            case  RspFileInfoType.WITHBODY:
              return sendRspFile2XX(conn, ii, rspFile.status, rspFile.header, rsp.path,
                                    rspFile.offset, rspFile.length, rsp.isHead);

            case RspFileInfoType.WITHOUTBODY:
              return sendRsp(conn, ii, rspFile.status, headers, { tag: RspType.RSPNOBODY });
          }
        });

    case RspType.RSPSTREAM:
      return conn.writeHead(status, headers)
        .chain(_ => rsp.body(buff => conn.sendAll(buff)))
        .map(_ => [P.just(status), P.nothing] as [P.Maybe<H.Status>, P.Maybe<number>]);

    /* istanbul ignore next */
    default:
      throw new TypeError('last argument to sendRsp must be Rsp');
  }
}
Example #3
0
 .chain(lr => {
   if (lr.tag === LookupResultType.LRNOTFOUND) {
     return lookupIndices(xs.slice(1));
   }
   if (settings.addTrailingSlash) {
     const redirect = addTrailingSlash(request);
     if (redirect != null) {
       return T.pure(P.left(redirect));
     }
   }
   return T.pure(P.right(lr));
 });
Example #4
0
 return lookupResult.chain(res => {
   if (P.isLeft(res)) {
     return T.pure({ tag: StaticResponseType.RAWREDIRECT, path: res.value } as StaticResponse);
   }
   const { value: result } = res;
   if (result.tag === LookupResultType.LRNOTFOUND) {
     return T.pure({ tag: StaticResponseType.NOTFOUND } as StaticResponse);
   }
   if (result.tag === LookupResultType.LRFILE) {
     return serveFile(settings, request, result.file);
   }
   return serveFolder(settings, pieces, request, result.folder);
 });
Example #5
0
export function parseRequestBody(ctx: HttpContext, opts?: MutterOptions): T.Task<[Params, Files]> {
  if (!requestHasBody(ctx.request)) return T.pure([{}, {}] as [Params, Files]);

  const mctype = getRequestBodyType(ctx.request);

  if (isNothing(mctype)) return T.pure([{}, {}] as [Params, Files]);

  const { value: ctype } = mctype;

  return ctype.tag === 'urlencoded' ? parseUrlEncodedBody(ctx, opts)
    : ctype.tag === 'multipart' ? parseMultipartBody(ctx, opts)
      : /* istanbul ignore next */ T.pure([{}, {}] as [Params, Files]);
}
Example #6
0
    .chain(efinfo => {
      if (isLeft(efinfo)) {
        assert.equal(true, false);
        return T.pure(false);
      }
      const { value: finfo } = efinfo;
      let hs = S.assign({}, rsp.header, {
        'Last-Modified': finfo.date
      });

      let rsp2 = rspFileInfo(RspFileInfoType.WITHBODY, rsp.status, hs, rsp.offset, rsp.length);
      assert.deepEqual(conditionalRequest(finfo, {}, headers), rsp2);
      return T.pure(false);
    });
Example #7
0
  return T.co(function* () {
    const id: string = yield generateSessionId;

    const authId: null | string = yield (
      auth === HasAuthId.HAS_AUTH_ID ? generateSessionId
        : T.pure(null));

    const keys: string[] = yield T.sequencePar(replicateArr(20, randomString(8)));
    const values: string[] = yield T.sequencePar(replicateArr(20, randomString(16)));
    const data = fromPairs(zip(keys, values));

    const now = Date.now();

    return T.pure(createSession(id, authId, data, now - 1000, now));
  });
Example #8
0
    function update(
      state: AppState<M, Q, S>,
      action: AppAction<M, Q, S, I>
    ): T.Task<AppState<M, Q, S>> {
      let next: Transition<M, S, I>,
        needsRender: boolean,
        nextState: AppState<M, Q, S>,
        appChange: AppChange<S, I>;
      switch (action.tag) {
        case AppActionType.INTERPRET:
          return state.interpret.loop(action.payload)
            .chain(ni => {
              return T.pure(S.assign({}, state, {
                interpret: ni
              }));
            });

        case AppActionType.ACTION:
          next = app.update(state.model, action.payload);
          needsRender = state.needsRender || state.model !== next.model;
          nextState = S.assign({}, state, {
            needsRender,
            model: next.model
          });
          appChange = { old: state.model, action: action.payload, model: nextState.model };
          return onChange(appChange).then(T.forInPar(next.effects, pushEffect)).map(() => nextState);

        case AppActionType.RESTORE:
          needsRender = state.needsRender || state.model !== action.payload;
          nextState = S.assign({}, state, { needsRender, model: action.payload });
          return T.pure(nextState);
      }
    }
Example #9
0
 .chain(() => {
   let st: AppState<M, Q, S> = { snabbdom
                               , interpret: it2
                               , needsRender: false
                               , model: app.init.model };
   return T.pure({ update, commit, init: st});
 });
Example #10
0
  it('storage.destroyAllOfAuthId should only delete relevant Auth Id', function* () {
    const master: Session = yield generateSession(HasAuthId.HAS_AUTH_ID);
    const authId = master.authId as string;

    const preslaves: Session[] = yield (replicateA(20, generateSession(HasAuthId.HAS_AUTH_ID))
      .concat(replicateA(20, generateSession(HasAuthId.NO_AUTH_ID)))
    );
    const slaves = preslaves.map(x => createSession(x.id, authId, x.data, x.createdAt, x.accessedAt));

    const others: Session[] = yield (replicateA(20, generateSession(HasAuthId.HAS_AUTH_ID))
      .concat(replicateA(20, generateSession(HasAuthId.NO_AUTH_ID)))
    );
    const allS = [master].concat(slaves, others);

    // insert session
    yield T.forInPar_([master].concat(preslaves, others), x => run(storage.insert(x)));
    yield T.forInPar_(slaves, x => run(storage.replace(x)));

    const xs: (Session | null)[] = yield T.forInPar(allS, x => run(storage.get(x.id)));
    assert.deepEqual(xs, allS);
    yield run(storage.destroyAllOfAuthId(authId));
    const ys: (Session | null)[] = yield T.forInPar(allS, x => run(storage.get(x.id)));
    const xxs = new Array(slaves.length + 1).fill(null);
    assert.deepEqual(ys, xxs.concat(others as any));
    return T.pure(true);
  });