]>
git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/lib/cpp/src/thrift/transport/THttpTransport.cpp
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
22 #include <thrift/transport/THttpTransport.h>
30 // Yeah, yeah, hacky to put these here, I know.
31 const char* THttpTransport::CRLF
= "\r\n";
32 const int THttpTransport::CRLF_LEN
= 2;
34 THttpTransport::THttpTransport(std::shared_ptr
<TTransport
> transport
)
35 : transport_(transport
),
49 void THttpTransport::init() {
50 httpBuf_
= (char*)std::malloc(httpBufSize_
+ 1);
51 if (httpBuf_
== nullptr) {
52 throw std::bad_alloc();
54 httpBuf_
[httpBufLen_
] = '\0';
57 THttpTransport::~THttpTransport() {
58 if (httpBuf_
!= nullptr) {
63 uint32_t THttpTransport::read(uint8_t* buf
, uint32_t len
) {
64 if (readBuffer_
.available_read() == 0) {
65 readBuffer_
.resetBuffer();
66 uint32_t got
= readMoreData();
71 return readBuffer_
.read(buf
, len
);
74 uint32_t THttpTransport::readEnd() {
75 // Read any pending chunked data (footers etc.)
77 while (!chunkedDone_
) {
84 uint32_t THttpTransport::readMoreData() {
87 if (httpPos_
== httpBufLen_
) {
99 size
= readContent(contentLength_
);
106 uint32_t THttpTransport::readChunked() {
109 char* line
= readLine();
110 uint32_t chunkSize
= parseChunkSize(line
);
111 if (chunkSize
== 0) {
112 readChunkedFooters();
115 length
+= readContent(chunkSize
);
116 // Read trailing CRLF after content
122 void THttpTransport::readChunkedFooters() {
123 // End of data, read footer lines until a blank one appears
125 char* line
= readLine();
126 if (strlen(line
) == 0) {
133 uint32_t THttpTransport::parseChunkSize(char* line
) {
134 char* semi
= strchr(line
, ';');
135 if (semi
!= nullptr) {
139 sscanf(line
, "%x", &size
);
143 uint32_t THttpTransport::readContent(uint32_t size
) {
144 uint32_t need
= size
;
146 uint32_t avail
= httpBufLen_
- httpPos_
;
148 // We have given all the data, reset position to head of the buffer
153 // Now have available however much we read
156 uint32_t give
= avail
;
160 readBuffer_
.write((uint8_t*)(httpBuf_
+ httpPos_
), give
);
167 char* THttpTransport::readLine() {
171 eol
= strstr(httpBuf_
+ httpPos_
, CRLF
);
174 if (eol
== nullptr) {
175 // Shift whatever we have now to front and refill
179 // Return pointer to next line
181 char* line
= httpBuf_
+ httpPos_
;
182 httpPos_
= static_cast<uint32_t>((eol
- httpBuf_
) + CRLF_LEN
);
188 void THttpTransport::shift() {
189 if (httpBufLen_
> httpPos_
) {
190 // Shift down remaining data and read more
191 uint32_t length
= httpBufLen_
- httpPos_
;
192 memmove(httpBuf_
, httpBuf_
+ httpPos_
, length
);
193 httpBufLen_
= length
;
198 httpBuf_
[httpBufLen_
] = '\0';
201 void THttpTransport::refill() {
202 uint32_t avail
= httpBufSize_
- httpBufLen_
;
203 if (avail
<= (httpBufSize_
/ 4)) {
205 char* tmpBuf
= (char*)std::realloc(httpBuf_
, httpBufSize_
+ 1);
206 if (tmpBuf
== nullptr) {
207 throw std::bad_alloc();
213 uint32_t got
= transport_
->read((uint8_t*)(httpBuf_
+ httpBufLen_
), httpBufSize_
- httpBufLen_
);
215 httpBuf_
[httpBufLen_
] = '\0';
218 throw TTransportException(TTransportException::END_OF_FILE
, "Could not refill buffer");
222 void THttpTransport::readHeaders() {
223 // Initialize headers state variables
226 chunkedDone_
= false;
229 // Control state flow
230 bool statusLine
= true;
231 bool finished
= false;
233 // Loop until headers are finished
235 char* line
= readLine();
237 if (strlen(line
) == 0) {
239 readHeaders_
= false;
242 // Must have been an HTTP 100, keep going for another status line
248 finished
= parseStatusLine(line
);
256 void THttpTransport::write(const uint8_t* buf
, uint32_t len
) {
257 writeBuffer_
.write(buf
, len
);
260 const std::string
THttpTransport::getOrigin() const {
261 std::ostringstream oss
;
262 if (!origin_
.empty()) {
263 oss
<< origin_
<< ", ";
265 oss
<< transport_
->getOrigin();