comparison UnitTests/ServerIndex.cpp @ 208:de640de989b8

HttpFileSender
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 28 Nov 2012 17:00:46 +0100
parents 7f74209ea0f8
children 9960642f0f45
comparison
equal deleted inserted replaced
207:7f74209ea0f8 208:de640de989b8
2 2
3 #include "../OrthancServer/DatabaseWrapper.h" 3 #include "../OrthancServer/DatabaseWrapper.h"
4 4
5 #include <ctype.h> 5 #include <ctype.h>
6 #include <glog/logging.h> 6 #include <glog/logging.h>
7
8 7
9 using namespace Orthanc; 8 using namespace Orthanc;
10 9
11 namespace 10 namespace
12 { 11 {
259 ASSERT_EQ("", listener.ancestorId_); // No more ancestor 258 ASSERT_EQ("", listener.ancestorId_); // No more ancestor
260 } 259 }
261 260
262 261
263 262
263
264 #include "../Core/HttpServer/FilesystemHttpSender.h"
265
264 #include "../Core/Toolbox.h" 266 #include "../Core/Toolbox.h"
265 #include "../Core/HttpServer/HttpOutput.h" 267 #include "../Core/HttpServer/HttpOutput.h"
266 #include "../Core/HttpServer/HttpHandler.h" 268 #include "../Core/HttpServer/HttpHandler.h"
269
270 #include "../Core/HttpServer/HttpFileSender.h"
271
267 272
268 namespace Orthanc 273 namespace Orthanc
269 { 274 {
270 class RestApiPath 275 class RestApiPath
271 { 276 {
371 bool Match(const UriComponents& uri) const 376 bool Match(const UriComponents& uri) const
372 { 377 {
373 Components components; 378 Components components;
374 UriComponents trailing; 379 UriComponents trailing;
375 return Match(components, trailing, uri); 380 return Match(components, trailing, uri);
376 }
377 };
378
379
380 class HttpFileSender
381 {
382 private:
383 std::string contentType_;
384 std::string filename_;
385
386 void SendHeader(HttpOutput& output)
387 {
388 std::string header;
389 header += "Content-Length: " + boost::lexical_cast<std::string>(GetFileSize()) + "\r\n";
390
391 if (contentType_.size() > 0)
392 {
393 header += "Content-Type: " + contentType_ + "\r\n";
394 }
395
396 if (filename_.size() > 0)
397 {
398 header += "Content-Disposition: attachment; filename=\"" + filename_ + "\"\r\n";
399 }
400
401 output.SendCustomOkHeader(header);
402 }
403
404 protected:
405 virtual uint64_t GetFileSize() = 0;
406
407 virtual bool SendData(HttpOutput& output) = 0;
408
409 public:
410 virtual ~HttpFileSender()
411 {
412 }
413
414 void ResetContentType()
415 {
416 contentType_.clear();
417 }
418
419 void SetContentType(const std::string& contentType)
420 {
421 contentType_ = contentType;
422 }
423
424 const std::string& GetContentType() const
425 {
426 return contentType_;
427 }
428
429 void ResetFilename()
430 {
431 contentType_.clear();
432 }
433
434 void SetFilename(const std::string& filename)
435 {
436 filename_ = filename;
437 }
438
439 const std::string& GetFilename() const
440 {
441 return filename_;
442 }
443
444 void Send(HttpOutput& output)
445 {
446 SendHeader(output);
447
448 if (!SendData(output))
449 {
450 output.SendHeader(Orthanc_HttpStatus_500_InternalServerError);
451 }
452 }
453 };
454
455
456 class FilesystemHttpSender : public HttpFileSender
457 {
458 private:
459 std::string path_;
460
461 protected:
462 virtual uint64_t GetFileSize()
463 {
464 return Toolbox::GetFileSize(path_);
465 }
466
467 virtual bool SendData(HttpOutput& output)
468 {
469 FILE* fp = fopen(path_.c_str(), "rb");
470 if (!fp)
471 {
472 return false;
473 }
474
475 std::vector<uint8_t> buffer(1024 * 1024); // Chunks of 1MB
476
477 for (;;)
478 {
479 size_t nbytes = fread(&buffer[0], 1, buffer.size(), fp);
480 if (nbytes == 0)
481 {
482 break;
483 }
484 else
485 {
486 output.Send(&buffer[0], nbytes);
487 }
488 }
489
490 fclose(fp);
491
492 return true;
493 }
494
495 public:
496 FilesystemHttpSender(const char* path) : path_(path)
497 {
498 boost::filesystem::path p(path);
499 SetFilename(p.filename().string());
500 SetContentType(Toolbox::AutodetectMimeType(p.filename().string()));
501 } 381 }
502 }; 382 };
503 383
504 384
505 class RestApiOutput 385 class RestApiOutput
992 872
993 httpServer.Start(); 873 httpServer.Start();
994 /*LOG(WARNING) << "REST has started"; 874 /*LOG(WARNING) << "REST has started";
995 Toolbox::ServerBarrier();*/ 875 Toolbox::ServerBarrier();*/
996 } 876 }
997
998
999 /**
1000
1001 output.AnswerBufferWithContentType(s, "application/json");
1002 output.AnswerFile(storage_, fileUuid, contentType, filename.c_str());
1003 output.Redirect("app/explorer.html");
1004 output.SendHeader(Orthanc_HttpStatus_415_UnsupportedMediaType);
1005 output.SendMethodNotAllowedError("GET");
1006
1007 **/