deligenius / multiparser

multipart/form-data parser for Deno servers
28 stars 7 forks source link

if send request many times, only half can request success #2

Closed lengfangbing closed 4 years ago

lengfangbing commented 4 years ago
async function parseFormData(contentType: string, request: ServerRequest) {
  const boundaryReg = /boundary=(.+)/i;
  const match = contentType.match(boundaryReg);
  const boundary = match?.[1];
  const res: {[key: string]: string | FormFile} = {};
  if(boundary){
    // const mr = new MultipartReader(request.r, boundary);
    // const form = await mr.readForm(2 * 1024 * 1024);
    const form: any = await multiParser(request);
    if(form){
      for(const [key, value] of form.entries()){
        const newValue: any = value || {};
        const val = <FormFile>value;
        if(val.content){
          const decoder = new TextDecoder();
          newValue.value = decoder.decode(val.content);
        }
        res[key] = <string | FormFile>newValue;
      }
    }
  }
  return res;
}

    const originRequest = ctx.request.serverRequest;
    const contentType = ctx.request.headers.get('content-type') || 'text';
    // set params data
    ctx.query = parseQuery(ctx.request.url.search.slice(1));
    // init request body
    const body = {type: '', value: {}};
    if(ctx.request.hasBody){
      // field to save body
      let _body: any;
      // field to save type
      let type: string;
      const contentTypeFilter = getContentType(contentType);
      // deal with form-data first
      if(contentTypeFilter.isFormData){
        _body = await parseFormData(contentType, originRequest);
        type = 'formData';
      }
   }

This is the result and some information image image I think this question casued by

 const form = await multiParser(request);

If I delete it, it worked

lengfangbing commented 4 years ago
async function parseFormData(contentType: string, request: ServerRequest) {
  const boundaryReg = /boundary=(.+)/i;
  const match = contentType.match(boundaryReg);
  const boundary = match?.[1];
  const res: {[key: string]: string | FormFile} = {};
  if(boundary){
    // const mr = new MultipartReader(request.r, boundary);
    // const form = await mr.readForm(2 * 1024 * 1024);
    const form: any = await multiParser(request);
    if(form){
      for(const [key, value] of form.entries()){
        const newValue: any = value || {};
        const val = <FormFile>value;
        if(val.content){
          const decoder = new TextDecoder();
          newValue.value = decoder.decode(val.content);
        }
        res[key] = <string | FormFile>newValue;
      }
    }
  }
  return res;
}

    const originRequest = ctx.request.serverRequest;
    const contentType = ctx.request.headers.get('content-type') || 'text';
    // set params data
    ctx.query = parseQuery(ctx.request.url.search.slice(1));
    // init request body
    const body = {type: '', value: {}};
    if(ctx.request.hasBody){
      // field to save body
      let _body: any;
      // field to save type
      let type: string;
      const contentTypeFilter = getContentType(contentType);
      // deal with form-data first
      if(contentTypeFilter.isFormData){
        _body = await parseFormData(contentType, originRequest);
        type = 'formData';
      }
   }

This is the result and some information image image I think this question casued by

 const form = await multiParser(request);

If I delete it, it worked

by the way, this issue only happened in oak

lengfangbing commented 4 years ago

I repeat your simple code. I used postman to send request. I used both oak and no framework but got same question. it didnt work. The same question. When you send the first request, you always get the correct response. But when you send a request then, it showed

image

I guess the MultipartReader instance readForm function has some trouble?

gjuoun commented 4 years ago

It's very difficult to see what you are trying to do.

如果你觉得中文能表达的更清楚,你可以我和打中文

lengfangbing commented 4 years ago

It's very difficult to see what you are trying to do.

如果你觉得中文能表达的更清楚,你可以我和打中文

好的, 有点尴尬..., 我的英语比较差 ... 这个问题有点奇怪, 我也不清楚具体是哪的问题. 我不在postman测试了. 在浏览器上用xhr或者fetch都试了, 当没有file的时候, 可以正常解析. 当带着file的时候, 第一次发送可以正常解析到, 也可以拿到content, 我再次发送请求浏览器会报跨域的问题 image 第三次发送就正常, 第四次会报跨域...然后周而复始

我看了下你的内部实现, 然后仿照着写了个, 我觉得可能问题是出在readForm这个方法. 可以看一下这个, https://github.com/denoland/deno/issues/5866 我把整个的测试过程和我的结论都放在了上面了, 希望你能看懂我写的英文...Y^Y

lengfangbing commented 4 years ago

It's very difficult to see what you are trying to do.

如果你觉得中文能表达的更清楚,你可以我和打中文

抱歉, 我知道原因了, 不是跨域, 而是400 Bad Request, 不过错误原因是一样的, 第一次点击是一切正常的, 第二次点击是报400 Bad Request. 第三次正常, 第四次就还是400 Bad Request. image image image

因为我有些方面不太懂, 多有打扰, 谢谢你~

gjuoun commented 4 years ago

这并不是multiparser的问题, 理应来说我应该close 这个issue.

我建议你用vscode的debug功能检查一下问题在哪

lengfangbing commented 4 years ago

这并不是multiparser的问题, 理应来说我应该close 这个issue.

我建议你用vscode的debug功能检查一下问题在哪

嗯嗯, 是的, 我现在发现了不是multiparser的问题. 好的, 这两天多谢你!

gjuoun commented 4 years ago

不客气