HttpRequest返回null实体,无法在服务器上提取body [英] HttpRequest returning null entity, cannot extract body on server

查看:1338
本文介绍了HttpRequest返回null实体,无法在服务器上提取body的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 apache httpcore组件并希望获取请求的正文。看起来默认的 DefaultHttpRequestParser 不会从其输入流中解析正文/实体。是否有一个类可以执行此操作?

I'm trying to parse an HTTP request using the apache httpcore components and want to grab the body of the request. It looks like the default DefaultHttpRequestParser doesn't parse the body/entity from its input stream. Is there a class that will do this?

不幸的是,我不能使用整个堆栈,需要直接从此输入流中提取请求。

Unfortunately I can't use the entire stack and need to pull the request straight from this input stream.

我的解析代码如下。看一些其他答案,似乎请求的主体应该作为一个实体可用。但是,每次我尝试进入实体时它都是null。

My parsing code is below. Looking at some of the other answers it appears that the body of the request should be available as an entity. However, every time I try to get at the entity it is null.

调试我看到缓冲区已读取但未使用正文,而 DefaultHttpRequestParser 似乎只是读取了标题。我应该用解析整个输入的解析吗?

Debugging I see that the buffer has read but not used the body and that DefaultHttpRequestParser seems to just read the header. Is there a parse I should be using to parse the entire input?

    InputStream is = socket.getInputStream();
    HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
    SessionInputBufferImpl buf = new SessionInputBufferImpl(metrics, 2048);
    buf.bind(is);

    DefaultHttpRequestParser reqParser = new DefaultHttpRequestParser(buf);
    HttpRequest req = reqParser.parse();
    if (req instanceof HttpEntityEnclosingRequest) {
        entity = ((HttpEntityEnclosingRequest)query).getEntity();
        //... entity is always null

如果我读取输入流我结束up with:

If I read the input stream I end up with:

POST / HTTP/1.1
User-Agent: curl/Q.XX.0 (linux-gnu) libcurl/Q.XX.0 OpenSSL/X.Y.Z zlib/A.B.C.D libidn/E.FF librtmp/G.H
Host: localhost:8088
Accept: */*
Content-Length: 333
Content-Type: multipart/form-data; boundary=----------------------------39203c7982df

------------------------------39203c7982df
Content-Disposition: form-data; name="fileupload"; filename="grun.sh"
Content-Type: application/octet-stream

#!/bin/bash -x
java -classpath lib/antlr-4.4-complete.jar:build/classes org.antlr.v4.runtime.misc.TestRig Typegroup "AHI" -tree

------------------------------39203c7982df--

[更新] Oleg有一个好的回答,但我可以将身体与请求联系起来或者做
我现在需要传递两个东西,身体和流吗?我将调查

[Update] Oleg has a good answer, but can I associate the body with the request or do I now need to pass two things around, the body and the stream? I'll be looking into

我得到了以下工作,但在最新版本中已弃用。

I got the following to work, but it's deprecated in the latest release.

        ...
        HttpEntityEnclosingRequest ereq = (HttpEntityEnclosingRequest) req;
        @SuppressWarnings("deprecation")
        EntityDeserializer ed = 
           new EntityDeserializer(new LaxContentLengthStrategy());
        @SuppressWarnings("deprecation")//ack!
        HttpEntity ent = ed.deserialize(buf, req);
        ereq.setEntity(ent);
        return ereq;

将Oleg的解决方案与上述结合起来我最终得到:

Combining Oleg's solution with the above I ended up with:

            HttpEntityEnclosingRequest ereq = (HttpEntityEnclosingRequest) req;

            ContentLengthStrategy contentLengthStrategy =
                        StrictContentLengthStrategy.INSTANCE;
            long len = contentLengthStrategy.determineLength(req);
            InputStream contentStream = null;
            if (len == ContentLengthStrategy.CHUNKED) {
                contentStream = new ChunkedInputStream(buf);
            } else if (len == ContentLengthStrategy.IDENTITY) {
                contentStream = new IdentityInputStream(buf);
            } else {
                contentStream = new ContentLengthInputStream(buf, len);
            }
            BasicHttpEntity ent = new BasicHttpEntity();
            ent.setContent(contentStream);
            ereq.setEntity(ent);
            return ereq;


推荐答案

InputStream is = socket.getInputStream();
HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
SessionInputBufferImpl buf = new SessionInputBufferImpl(metrics, 2048);
buf.bind(is);

DefaultHttpRequestParser reqParser = new DefaultHttpRequestParser(buf);
HttpRequest req = reqParser.parse();
InputStream contentStream = null;
if (req instanceof HttpEntityEnclosingRequest) {
    ContentLengthStrategy contentLengthStrategy = StrictContentLengthStrategy.INSTANCE;
    long len = contentLengthStrategy.determineLength(req);
    if (len == ContentLengthStrategy.CHUNKED) {
        contentStream = new ChunkedInputStream(buf);
    } else if (len == ContentLengthStrategy.IDENTITY) {
        contentStream = new IdentityInputStream(buf);
    } else {
        contentStream = new ContentLengthInputStream(buf, len);
    }
}
// Do something useful with the content stream (if non null)

HttpCore中的消息解析器仅解析消息头。但是,可以从会话输入缓冲区继续读取并读取消息正文内容,直到消息结束(取决于使用的描述符)

Message parsers in HttpCore parse message heads only. However, one can proceed reading from the session input buffer and read message body content until the end of message (depending on the delineator used)

这篇关于HttpRequest返回null实体,无法在服务器上提取body的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆