我正在为透明代理编写HTTP解析器.什么让我感到困惑的是Trailer:规格中提到的Transfer-Encoding: chunked.它是什么样子的?
通常,HTTP chunked会像这样结束.
0\r\n
\r\n
Run Code Online (Sandbox Code Playgroud)
我感到困惑的是如果有某种尾随标题,如何检测块的结尾...
更新:我相信一个简单的\r\n\r\n即空行足以检测尾随标题的结尾......这是正确的吗?
我正在使用HttpURLConnection向服务器写入文件,其中一些文件很大.
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
Run Code Online (Sandbox Code Playgroud)
前一阵子我写了1 GB或更多的对象.我通过将其设置为流更易管理的块大小来修复它.
final int bufferSize = 1024 * 1024;
[...]
conn.setChunkedStreamingMode(bufferSize);
Run Code Online (Sandbox Code Playgroud)
它在我的笔记本电脑上运行良好,但在其他机器上却崩溃了.经过调查,我发现原因是在写入输出流时发生了内存不足错误.
final OutputStream out = conn.getOutputStream();
final long bytesWritten = IOUtils.copyLarge(in, out);
Run Code Online (Sandbox Code Playgroud)
在copyLarge例程中,我发现它能够执行262145次4096字节的迭代,当它试图越过1 GB行时失败.为java应用程序分配更多内存似乎可以防止这些崩溃,但我认为这应该是不必要的.如果它正在写1 MB的块,那么它应该失败,迭代次数少得多,或者反复写1 MB而没有问题.
更新:结果显示在某些机器上实际上没有调用ChunkedStreamingMode的行设置.如果您没有设置固定/分块流模式,HttpURLConnection只会将所有内容发送到PosterOutputStream/ByteArrayOutputStream.
有些专家可以解释两者之间的差异吗?是不是chunked是一个流协议而多部分不是?使用multipart有什么好处?
HTTP 1.1客户端是否可以设置一个标头值,指示不应对请求的响应进行分块?或者是防止这种情况的唯一方法是发送HTTP 1.0请求?我试过谷歌搜索,但我能找到的方法是禁用HTTP 1.1服务器上的分块传输,所以我猜测它在客户端是不可能的,但我想我还是会问.
我一直在努力处理几个类实现,以检索分块数据但没有成功.以下是一个有问题的简化代码模块.在网上浏览之后,过去似乎出现了问题(2009年,2010年;版本1.1,1.5),但现在应该解决这些问题.我没有看到Android平台对此协议有任何明确的成功.
救命!
如果我输入无效令牌,我能看到一些响应 - Web服务将响应应用程序错误消息.但是,有效的url和令牌只会响应检测到的chunked协议(isChunked()返回true),但没有任何内容被读取,也没有任何超时等等.
从命令行使用CURL发出的完全相同的URL按预期工作,并显示连续内容(来自Web服务的已发布数据).
是否存在任何Web服务端黑客,例如,添加更多行尾,强制接收流?
URI uri;
try {
uri = new URI("http://cws.mycompany.com/service/events?accesskeyid=8226f3ddc65a420abc391d8f1fe12de44766146762_1298174060748");
HttpClient httpClient=new DefaultHttpClient();
HttpGet httpGet=new HttpGet(uri);
ResponseHandler<String> rh=new BasicResponseHandler();
String responseString=httpClient.execute(httpGet,rh);
Log.d(TAG, "response as string:\n" + responseString);
} catch (URISyntaxException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
} catch (ClientProtocolException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
} catch (IOException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud) 我使用Apache HttpClient来发布多个文件服务器.这是代码:
public static HttpResponse stringResponsePost(String urlString, String content, byte[] image,
HttpContext localContext, HttpClient httpclient) throws Exception {
URL url = new URL(URLDecoder.decode(urlString, "utf-8"));
URI u = url.toURI();
HttpPost post = new HttpPost();
post.setURI(u);
MultipartEntity reqEntity = new MultipartEntity();
StringBody sb = new StringBody(content, HTTP_CONTENT_TYPE_JSON, Charset.forName("UTF-8"));
ByteArrayBody ib = new ByteArrayBody(image, HTTP_CONTENT_TYPE_JPEG, "image");
reqEntity.addPart("interview_data", sb);
reqEntity.addPart("interview_image", ib);
post.setEntity(reqEntity);
HttpResponse response = null;
response = httpclient.execute(post, localContext);
return response;
}
Run Code Online (Sandbox Code Playgroud)
问题是,MultipartEntityclass只有isChunked()方法(总是返回false),如果我希望为我的multipart实体启用chucked编码,则没有"setChunked(boolean)"选项.
我的问题是:
HTTP multipart和chunking可以根据协议规范共存吗?如果不是,为什么像其他实体 …
我有以下问题:我正在创建一个非常大的SOAP请求(数据是一个编码为Base64字符串的视频),因此我不能将其作为原始SOAP请求发送,而是需要在HTTP 1.1块中发送它.我似乎无法弄明白该怎么做.我在这里使用了代码: 对于分块传输编码,NSURLConnection的替代方法是什么, 但它似乎没有做我认为应该做的事情 - 我可以看到请求作为单个请求而不是许多块到达服务器上(我在服务器上使用WireShark来查看传入的流量.)
我知道Android上的类似功能使用Apache Foundations HTTP库进行Java工作 - 有了这些,任何预先未指定长度的HTTP请求都会作为HTTP 1.1 Chunked Request传输 - 我可以看到这些请求到达了服务器作为单独的块...我想模仿它.
(更新:似乎我AFNetworking可能有功能,但我没有找到任何关于如何使用它的例子.)
这是我的代码,或多或少:
NSString *soapBody = ....; //some correctly formed SOAP request XML here
NSURL *url = [NSURL URLWithString:...];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
[request addValue: ... forHTTPHeaderField:@"SOAPAction"];
[request setHTTPMethod:@"POST"];
[request addValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:[soapBody dataUsingEncoding:NSUTF8StringEncoding]];
ChunkedTransferConnection* connection = [ChunkedTransferConnection alloc];
[connection establishConnectionWithRequest:request];
Run Code Online (Sandbox Code Playgroud)
ChunkedTransferConnection的实现如下
@implementation ChunkedTransferConnection
@synthesize p_connection;
@synthesize p_responseData;
- (void)establishConnectionWithRequest:(NSMutableURLRequest *)request
{
self.p_responseData = [[NSMutableData alloc] initWithLength:0] ;
self.p_connection = [[NSURLConnection …Run Code Online (Sandbox Code Playgroud) 我以分块传输编码格式向客户端发送大量数据.
我应该如何处理出现的任何错误中途响应的写作过程中?
我想知道是否有任何HTTP规范建议的做法,以便客户知道确实响应不是一个成功的但服务器遇到了一些问题.
我正在ChunkedEncodingError(e)使用Python请求.我正在使用以下内容来删除JSON:
r = requests.get(url, headers=auth, stream=True)
Run Code Online (Sandbox Code Playgroud)
并使用回车作为分隔符迭代每一行,这就是此API区分不同JSON事件的方式.
for d in r.iter_lines(delimiter="\n"):
d += "\n"
sock.send(d)
Run Code Online (Sandbox Code Playgroud)
我正在对回车进行分界,然后将其添加回作为端点我正在推动日志实际上期望在每个事件结束时回车.这似乎适用于大约100k日志文件.当我尝试拨打更大的电话时,我会抛出以下内容:
for d in r.iter_lines(delimiter="\n"):
logs_1 | File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 783, in iter_lines
logs_1 | for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode):
logs_1 | File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 742, in generate
logs_1 | raise ChunkedEncodingError(e)
logs_1 | requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))
Run Code Online (Sandbox Code Playgroud)
更新:我发现API NoneType也在某个时刻发回.那么如何在响应中的某处解释这个空字节而不会破坏一切?每个单独的事件都以a结束\n,我需要能够单独检查每个事件.我应该把内容分块而不是iter_lines?然后确保NoneType块中没有?这样我就不会试图iter_lines超过它NoneType并且它会爆炸?
我在这上面花了一天时间,但找不到有效的解决方案。在我们的应用程序中,我们有几个端点可以返回大响应。我一直在尝试寻找一种机制,允许我们在处理数据库查询结果时流式传输响应。主要目标是限制服务端的峰值内存使用(不需要内存中的整个响应)并最小化响应第一个字节的时间(如果响应没有开始进入,客户端系统会超时)指定时间 - 10 分钟)。我真的很惊讶这这么难。
我找到了 StreamingResponseBody ,它看起来很接近我们想要的东西,虽然我们并不真正需要异步方面,但我们只希望能够在处理查询结果时开始流式传输响应。我也尝试过其他方法,例如使用@ResponseBody 进行注释、返回 void 并添加 OutputStream 的参数,但这不起作用,因为传递的 OutputStream 基本上只是一个缓存整个结果的 CachingOutputStream。这是我现在所拥有的......
资源方法:
@GetMapping(value = "/catalog/features")
public StreamingResponseBody findFeatures(
@RequestParam("provider-name") String providerName,
@RequestParam(name = "category", required = false) String category,
@RequestParam("date") String date,
@RequestParam(value = "version-state", defaultValue = "*") String versionState) {
CatalogVersionState catalogVersionState = getCatalogVersionState(versionState);
log.info("GET - Starting DB query...");
final List<Feature> features
= featureService.findFeatures(providerName,
category,
ZonedDateTime.parse(date),
catalogVersionState);
log.info("GET - Query done!");
return new StreamingResponseBody() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
log.info("GET - …Run Code Online (Sandbox Code Playgroud) http-chunked ×10
http ×6
chunked ×3
java ×3
android ×1
chunking ×1
http-1.1 ×1
ios ×1
objective-c ×1
python ×1
soap ×1
spring-boot ×1
streaming ×1