Mercurial > hg > orthanc
annotate OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp @ 5853:4d932683049d get-scu tip
very first implementation of C-Get SCU
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 29 Oct 2024 17:25:49 +0100 |
parents | f7adfb22e20e |
children |
rev | line source |
---|---|
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
1 /** |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
2 * Orthanc - A Lightweight, RESTful DICOM Store |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
4 * Department, University Hospital of Liege, Belgium |
5640
f7adfb22e20e
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
f7adfb22e20e
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5485
diff
changeset
|
6 * Copyright (C) 2024-2024 Orthanc Team SRL, Belgium |
5485
48b8dae6dc77
upgrade to year 2024
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5432
diff
changeset
|
7 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
8 * |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
9 * This program is free software: you can redistribute it and/or |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
10 * modify it under the terms of the GNU Lesser General Public License |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
11 * as published by the Free Software Foundation, either version 3 of |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
12 * the License, or (at your option) any later version. |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
13 * |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
14 * This program is distributed in the hope that it will be useful, but |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
15 * WITHOUT ANY WARRANTY; without even the implied warranty of |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
17 * Lesser General Public License for more details. |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
18 * |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
19 * You should have received a copy of the GNU Lesser General Public |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
20 * License along with this program. If not, see |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
21 * <http://www.gnu.org/licenses/>. |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
22 **/ |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
23 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
24 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
25 #include "../PrecompiledHeaders.h" |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
26 #include "MultipartStreamReader.h" |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
27 |
4453
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
28 #include "../Logging.h" |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
29 #include "../OrthancException.h" |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
30 #include "../Toolbox.h" |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
31 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
32 #include <boost/algorithm/string/predicate.hpp> |
4304 | 33 #include <boost/lexical_cast.hpp> |
3411 | 34 |
4361
98f55e7df5ab
rollback incorrect removal for msvc2008
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4360
diff
changeset
|
35 #if defined(_MSC_VER) |
98f55e7df5ab
rollback incorrect removal for msvc2008
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4360
diff
changeset
|
36 # include <BaseTsd.h> // Definition of ssize_t |
98f55e7df5ab
rollback incorrect removal for msvc2008
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4360
diff
changeset
|
37 #endif |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
38 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
39 namespace Orthanc |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
40 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
41 static void ParseHeaders(MultipartStreamReader::HttpHeaders& headers, |
4652
0ad5736c8d62
use plain C strings in MultipartStreamReader instead of std::string to allow further optimizations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4476
diff
changeset
|
42 const char* start, |
0ad5736c8d62
use plain C strings in MultipartStreamReader instead of std::string to allow further optimizations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4476
diff
changeset
|
43 const char* end /* exclusive */) |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
44 { |
4652
0ad5736c8d62
use plain C strings in MultipartStreamReader instead of std::string to allow further optimizations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4476
diff
changeset
|
45 assert(start <= end); |
0ad5736c8d62
use plain C strings in MultipartStreamReader instead of std::string to allow further optimizations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4476
diff
changeset
|
46 std::string tmp(start, end - start); |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
47 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
48 std::vector<std::string> lines; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
49 Toolbox::TokenizeString(lines, tmp, '\n'); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
50 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
51 headers.clear(); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
52 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
53 for (size_t i = 0; i < lines.size(); i++) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
54 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
55 size_t separator = lines[i].find(':'); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
56 if (separator != std::string::npos) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
57 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
58 std::string key = Toolbox::StripSpaces(lines[i].substr(0, separator)); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
59 std::string value = Toolbox::StripSpaces(lines[i].substr(separator + 1)); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
60 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
61 Toolbox::ToLowerCase(key); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
62 headers[key] = value; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
63 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
64 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
65 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
66 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
67 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
68 static bool LookupHeaderSizeValue(size_t& target, |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
69 const MultipartStreamReader::HttpHeaders& headers, |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
70 const std::string& key) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
71 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
72 MultipartStreamReader::HttpHeaders::const_iterator it = headers.find(key); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
73 if (it == headers.end()) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
74 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
75 return false; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
76 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
77 else |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
78 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
79 int64_t value; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
80 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
81 try |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
82 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
83 value = boost::lexical_cast<int64_t>(it->second); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
84 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
85 catch (boost::bad_lexical_cast&) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
86 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
87 throw OrthancException(ErrorCode_ParameterOutOfRange); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
88 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
89 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
90 if (value < 0) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
91 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
92 throw OrthancException(ErrorCode_ParameterOutOfRange); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
93 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
94 else |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
95 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
96 target = static_cast<size_t>(value); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
97 return true; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
98 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
99 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
100 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
101 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
102 |
4653
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
103 void MultipartStreamReader::ParseBlock(const void* data, |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
104 size_t size) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
105 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
106 if (handler_ == NULL || |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
107 state_ == State_Done || |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
108 size == 0) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
109 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
110 return; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
111 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
112 else |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
113 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
114 const char* current = reinterpret_cast<const char*>(data); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
115 const char* corpusEnd = current + size; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
116 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
117 if (state_ == State_UnusedArea) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
118 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
119 /** |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
120 * "Before the first boundary is an area that is ignored by |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
121 * MIME-compliant clients. This area is generally used to put |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
122 * a message to users of old non-MIME clients." |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
123 * https://en.wikipedia.org/wiki/MIME#Multipart_messages |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
124 **/ |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
125 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
126 if (boundaryMatcher_.Apply(current, corpusEnd)) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
127 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
128 current = boundaryMatcher_.GetMatchBegin(); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
129 state_ = State_Content; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
130 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
131 else |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
132 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
133 // We have not seen the end of the unused area yet |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
134 assert(current <= corpusEnd); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
135 buffer_.AddChunk(current, corpusEnd - current); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
136 return; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
137 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
138 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
139 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
140 for (;;) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
141 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
142 assert(current <= corpusEnd); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
143 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
144 size_t patternSize = boundaryMatcher_.GetPattern().size(); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
145 size_t remainingSize = corpusEnd - current; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
146 if (remainingSize < patternSize + 2) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
147 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
148 break; // Not enough data available |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
149 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
150 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
151 std::string boundary(current, current + patternSize + 2); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
152 if (boundary == boundaryMatcher_.GetPattern() + "--") |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
153 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
154 state_ = State_Done; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
155 return; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
156 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
157 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
158 if (boundary != boundaryMatcher_.GetPattern() + "\r\n") |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
159 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
160 throw OrthancException(ErrorCode_NetworkProtocol, |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
161 "Garbage between two items in a multipart stream"); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
162 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
163 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
164 const char* start = current + patternSize + 2; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
165 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
166 if (!headersMatcher_.Apply(start, corpusEnd)) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
167 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
168 break; // Not enough data available |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
169 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
170 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
171 HttpHeaders headers; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
172 ParseHeaders(headers, start, headersMatcher_.GetMatchBegin()); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
173 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
174 size_t contentLength = 0; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
175 if (!LookupHeaderSizeValue(contentLength, headers, "content-length")) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
176 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
177 if (boundaryMatcher_.Apply(headersMatcher_.GetMatchEnd(), corpusEnd)) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
178 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
179 assert(headersMatcher_.GetMatchEnd() <= boundaryMatcher_.GetMatchBegin()); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
180 size_t d = boundaryMatcher_.GetMatchBegin() - headersMatcher_.GetMatchEnd(); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
181 if (d <= 1) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
182 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
183 throw OrthancException(ErrorCode_NetworkProtocol); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
184 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
185 else |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
186 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
187 contentLength = d - 2; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
188 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
189 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
190 else |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
191 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
192 break; // Not enough data available to have a full part |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
193 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
194 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
195 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
196 // "static_cast<>" to avoid warning about signed vs. unsigned comparison |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
197 assert(headersMatcher_.GetMatchEnd() <= corpusEnd); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
198 if (contentLength + 2 > static_cast<size_t>(corpusEnd - headersMatcher_.GetMatchEnd())) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
199 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
200 break; // Not enough data available to have a full part |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
201 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
202 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
203 const char* p = headersMatcher_.GetMatchEnd() + contentLength; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
204 if (p[0] != '\r' || |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
205 p[1] != '\n') |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
206 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
207 throw OrthancException(ErrorCode_NetworkProtocol, |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
208 "No endline at the end of a part"); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
209 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
210 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
211 handler_->HandlePart(headers, headersMatcher_.GetMatchEnd(), contentLength); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
212 current = headersMatcher_.GetMatchEnd() + contentLength + 2; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
213 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
214 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
215 if (current != corpusEnd) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
216 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
217 assert(current < corpusEnd); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
218 buffer_.AddChunk(current, corpusEnd - current); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
219 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
220 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
221 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
222 |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
223 |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
224 void MultipartStreamReader::ParseStream() |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
225 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
226 if (handler_ == NULL || |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
227 state_ == State_Done) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
228 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
229 return; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
230 } |
4653
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
231 else |
4652
0ad5736c8d62
use plain C strings in MultipartStreamReader instead of std::string to allow further optimizations
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4476
diff
changeset
|
232 { |
4653
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
233 std::string corpus; |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
234 buffer_.Flatten(corpus); |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
235 |
4653
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
236 if (!corpus.empty()) |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
237 { |
4653
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
238 ParseBlock(corpus.c_str(), corpus.size()); |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
239 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
240 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
241 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
242 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
243 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
244 MultipartStreamReader::MultipartStreamReader(const std::string& boundary) : |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
245 state_(State_UnusedArea), |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
246 handler_(NULL), |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
247 headersMatcher_("\r\n\r\n"), |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
248 boundaryMatcher_("--" + boundary), |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
249 blockSize_(10 * 1024 * 1024) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
250 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
251 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
252 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
253 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
254 void MultipartStreamReader::SetBlockSize(size_t size) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
255 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
256 if (size == 0) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
257 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
258 throw OrthancException(ErrorCode_ParameterOutOfRange); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
259 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
260 else |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
261 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
262 blockSize_ = size; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
263 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
264 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
265 |
4298 | 266 size_t MultipartStreamReader::GetBlockSize() const |
267 { | |
268 return blockSize_; | |
269 } | |
270 | |
271 void MultipartStreamReader::SetHandler(MultipartStreamReader::IHandler &handler) | |
272 { | |
273 handler_ = &handler; | |
274 } | |
275 | |
276 | |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
277 void MultipartStreamReader::AddChunk(const void* chunk, |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
278 size_t size) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
279 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
280 if (state_ != State_Done && |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
281 size != 0) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
282 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
283 size_t oldSize = buffer_.GetNumBytes(); |
4653
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
284 if (oldSize == 0) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
285 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
286 /** |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
287 * Optimization in Orthanc 1.9.3: Directly parse the input |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
288 * buffer instead of going through the ChunkedBuffer if the |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
289 * latter is still empty. This notably avoids one memcpy() in |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
290 * STOW-RS server if chunked transfers is disabled. |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
291 **/ |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
292 ParseBlock(chunk, size); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
293 } |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
294 else |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
295 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
296 buffer_.AddChunk(chunk, size); |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
297 |
4653
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
298 if (oldSize / blockSize_ != buffer_.GetNumBytes() / blockSize_) |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
299 { |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
300 ParseStream(); |
3d5d6e2dcf3f
memory optimization in Orthanc::MultipartStreamReader if parsing one single big block
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4652
diff
changeset
|
301 } |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
302 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
303 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
304 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
305 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
306 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
307 void MultipartStreamReader::AddChunk(const std::string& chunk) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
308 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
309 if (!chunk.empty()) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
310 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
311 AddChunk(chunk.c_str(), chunk.size()); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
312 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
313 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
314 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
315 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
316 void MultipartStreamReader::CloseStream() |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
317 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
318 if (buffer_.GetNumBytes() != 0) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
319 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
320 ParseStream(); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
321 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
322 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
323 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
324 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
325 bool MultipartStreamReader::GetMainContentType(std::string& contentType, |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
326 const HttpHeaders& headers) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
327 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
328 HttpHeaders::const_iterator it = headers.find("content-type"); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
329 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
330 if (it == headers.end()) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
331 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
332 return false; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
333 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
334 else |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
335 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
336 contentType = it->second; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
337 return true; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
338 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
339 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
340 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
341 |
4333
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
342 static void RemoveSurroundingQuotes(std::string& value) |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
343 { |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
344 if (value.size() >= 2 && |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
345 value[0] == '"' && |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
346 value[value.size() - 1] == '"') |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
347 { |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
348 value = value.substr(1, value.size() - 2); |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
349 } |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
350 } |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
351 |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
352 |
3399
4e8205871967
OrthancPluginRegisterMultipartRestCallback() is working
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3398
diff
changeset
|
353 bool MultipartStreamReader::ParseMultipartContentType(std::string& contentType, |
4e8205871967
OrthancPluginRegisterMultipartRestCallback() is working
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3398
diff
changeset
|
354 std::string& subType, |
4e8205871967
OrthancPluginRegisterMultipartRestCallback() is working
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3398
diff
changeset
|
355 std::string& boundary, |
4e8205871967
OrthancPluginRegisterMultipartRestCallback() is working
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3398
diff
changeset
|
356 const std::string& contentTypeHeader) |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
357 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
358 std::vector<std::string> tokens; |
4297 | 359 Toolbox::TokenizeString(tokens, contentTypeHeader, ';'); |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
360 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
361 if (tokens.empty()) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
362 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
363 return false; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
364 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
365 |
4297 | 366 contentType = Toolbox::StripSpaces(tokens[0]); |
367 Toolbox::ToLowerCase(contentType); | |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
368 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
369 if (contentType.empty()) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
370 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
371 return false; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
372 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
373 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
374 bool valid = false; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
375 subType.clear(); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
376 |
4453
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
377 for (size_t i = 1; i < tokens.size(); i++) |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
378 { |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
379 std::vector<std::string> items; |
4297 | 380 Toolbox::TokenizeString(items, tokens[i], '='); |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
381 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
382 if (items.size() == 2) |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
383 { |
4297 | 384 if (boost::iequals("boundary", Toolbox::StripSpaces(items[0]))) |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
385 { |
4297 | 386 boundary = Toolbox::StripSpaces(items[1]); |
4333
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
387 |
5432
59e3b6f8c5be
migration to UCLouvain servers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5185
diff
changeset
|
388 // https://orthanc.uclouvain.be/bugs/show_bug.cgi?id=190 |
4333
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
389 RemoveSurroundingQuotes(boundary); |
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
390 |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
391 valid = !boundary.empty(); |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
392 } |
4297 | 393 else if (boost::iequals("type", Toolbox::StripSpaces(items[0]))) |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
394 { |
4297 | 395 subType = Toolbox::StripSpaces(items[1]); |
396 Toolbox::ToLowerCase(subType); | |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
397 |
5432
59e3b6f8c5be
migration to UCLouvain servers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5185
diff
changeset
|
398 // https://orthanc.uclouvain.be/bugs/show_bug.cgi?id=54 |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
399 // https://tools.ietf.org/html/rfc7231#section-3.1.1.1 |
4333
a85e74235a78
fix parsing of multipart boundaries, to resolve issue #190 in STOW-RS of DICOMweb plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
400 RemoveSurroundingQuotes(subType); |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
401 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
402 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
403 } |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
404 |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
405 return valid; |
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
406 } |
4453
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
407 |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
408 |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
409 bool MultipartStreamReader::ParseHeaderArguments(std::string& main, |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
410 std::map<std::string, std::string>& arguments, |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
411 const std::string& header) |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
412 { |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
413 std::vector<std::string> tokens; |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
414 Toolbox::TokenizeString(tokens, header, ';'); |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
415 |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
416 if (tokens.empty()) |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
417 { |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
418 return false; |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
419 } |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
420 |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
421 main = Toolbox::StripSpaces(tokens[0]); |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
422 Toolbox::ToLowerCase(main); |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
423 if (main.empty()) |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
424 { |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
425 return false; |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
426 } |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
427 |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
428 arguments.clear(); |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
429 |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
430 for (size_t i = 1; i < tokens.size(); i++) |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
431 { |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
432 std::vector<std::string> items; |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
433 Toolbox::TokenizeString(items, tokens[i], '='); |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
434 |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
435 if (items.size() > 2) |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
436 { |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
437 return false; |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
438 } |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
439 else if (!items.empty()) |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
440 { |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
441 std::string key = Toolbox::StripSpaces(items[0]); |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
442 Toolbox::ToLowerCase(key); |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
443 |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
444 if (arguments.find(key) != arguments.end()) |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
445 { |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
446 LOG(ERROR) << "The same argument was provided twice in an HTTP header: \"" |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
447 << key << "\" in \"" << header << "\""; |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
448 return false; |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
449 } |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
450 else if (!key.empty()) |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
451 { |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
452 if (items.size() == 1) |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
453 { |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
454 arguments[key] = ""; |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
455 } |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
456 else |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
457 { |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
458 assert(items.size() == 2); |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
459 std::string value = Toolbox::StripSpaces(items[1]); |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
460 RemoveSurroundingQuotes(value); |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
461 arguments[key] = value; |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
462 } |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
463 } |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
464 } |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
465 } |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
466 |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
467 return true; |
4f8e77c650e8
new function MultipartStreamReader::ParseHeaderArguments()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
468 } |
3398
4acd1431e603
new classes: StringMatcher and MultipartStreamReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
469 } |