Mercurial > hg > orthanc
comparison Core/HttpServer/HttpServer.cpp @ 3356:f744730c294b
Orthanc now accepts chunked transfer encoding
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 29 Apr 2019 17:24:30 +0200 |
parents | 10e2b9f4162f |
children | c0aa5f1cf2f5 |
comparison
equal
deleted
inserted
replaced
3354:e60e194531e5 | 3356:f744730c294b |
---|---|
306 const IHttpHandler::Arguments& headers) | 306 const IHttpHandler::Arguments& headers) |
307 { | 307 { |
308 IHttpHandler::Arguments::const_iterator cs = headers.find("content-length"); | 308 IHttpHandler::Arguments::const_iterator cs = headers.find("content-length"); |
309 if (cs == headers.end()) | 309 if (cs == headers.end()) |
310 { | 310 { |
311 return PostDataStatus_NoLength; | 311 // TODO - Avoid storing this entirely in RAM, use temporary |
312 } | 312 // files instead. The amount of RAM needed to receive one body |
313 | 313 // of "N" bytes is currently "2*N" bytes (one copy in "buffer", |
314 int length; | 314 // one copy in "postData"). With a |
315 try | 315 // "ChunkedBufferInTemporaryFiles", one would need "N" bytes (in |
316 { | 316 // "postData" only). |
317 length = boost::lexical_cast<int>(cs->second); | 317 |
318 } | 318 std::string tmp(1024 * 1024, 0); |
319 catch (boost::bad_lexical_cast&) | 319 |
320 { | 320 ChunkedBuffer buffer; |
321 return PostDataStatus_NoLength; | 321 |
322 } | 322 for (;;) |
323 | 323 { |
324 if (length < 0) | 324 int r = mg_read(connection, &tmp[0], tmp.size()); |
325 { | 325 if (r < 0) |
326 length = 0; | 326 { |
327 } | 327 return PostDataStatus_Failure; |
328 | 328 } |
329 postData.resize(length); | 329 else if (r == 0) |
330 | 330 { |
331 size_t pos = 0; | 331 break; |
332 while (length > 0) | 332 } |
333 { | 333 else |
334 int r = mg_read(connection, &postData[pos], length); | 334 { |
335 if (r <= 0) | 335 buffer.AddChunk(tmp.c_str(), r); |
336 { | 336 } |
337 return PostDataStatus_Failure; | 337 } |
338 } | 338 |
339 | 339 buffer.Flatten(postData); |
340 assert(r <= length); | 340 |
341 length -= r; | 341 return PostDataStatus_Success; |
342 pos += r; | 342 } |
343 } | 343 else |
344 | 344 { |
345 return PostDataStatus_Success; | 345 int length; |
346 try | |
347 { | |
348 length = boost::lexical_cast<int>(cs->second); | |
349 } | |
350 catch (boost::bad_lexical_cast&) | |
351 { | |
352 return PostDataStatus_NoLength; | |
353 } | |
354 | |
355 if (length < 0) | |
356 { | |
357 length = 0; | |
358 } | |
359 | |
360 postData.resize(length); | |
361 | |
362 size_t pos = 0; | |
363 while (length > 0) | |
364 { | |
365 int r = mg_read(connection, &postData[pos], length); | |
366 if (r <= 0) | |
367 { | |
368 return PostDataStatus_Failure; | |
369 } | |
370 | |
371 assert(r <= length); | |
372 length -= r; | |
373 pos += r; | |
374 } | |
375 | |
376 return PostDataStatus_Success; | |
377 } | |
346 } | 378 } |
347 | 379 |
348 | 380 |
349 | 381 |
350 static PostDataStatus ParseMultipartPost(std::string &completedFile, | 382 static PostDataStatus ParseMultipartPost(std::string &completedFile, |