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,