num_crlf++;
continue;
}
- else {
+ else { // FIXIT-M there needs to be an event for this
complete = true;
return SCAN_ABORT;
}
complete = true;
return SCAN_FOUND;
}
- if (num_crlf == 1) {
+ if (num_crlf == 1) { // FIXIT-M there needs to be an event for this
// CR not followed by LF
complete = true;
return SCAN_ABORT;
ScanResult NHttpHeaderSplitter::split(const uint8_t* buffer, uint32_t length) {
conditional_reset();
if (peek_status == SCAN_FOUND) {
+ complete = true;
return SCAN_FOUND;
}
buffer += peek_octets;
length -= peek_octets;
+
+ // Header separators: leading \r\n, leading \n, nonleading \r\n\r\n, nonleading \n\r\n, nonleading \r\n\n, and
+ // nonleading \n\n. The separator itself becomes num_excess which is discarded during reassemble().
for (uint32_t k = 0; k < length; k++) {
if (buffer[k] == '\n') {
num_crlf++;
assert(octets_seen == 0);
peek_status = split(buffer, length);
peek_octets = length;
+ complete = false;
return peek_status;
}
void NHttpHeaderSplitter::conditional_reset() {
if (complete) {
peek_octets = 0;
- peek_status = SCAN_NOTFOUND;
first_lf = 0;
+ peek_status = SCAN_NOTFOUND;
}
NHttpSplitter::conditional_reset();
}
virtual bool partial_ok() const { return true; };
protected:
- uint32_t octets_seen = 0;
+ uint32_t octets_seen = 0; // number of octets processed by previous split() calls that returned NOTFOUND
uint32_t num_crlf = 0;
uint32_t num_flush = 0;
bool complete = false;
class NHttpStartSplitter : public NHttpSplitter {
public:
- NHttpEnums::ScanResult split(const uint8_t* buffer, uint32_t length);
- uint32_t get_num_excess() const { return num_crlf; };
+ NHttpEnums::ScanResult split(const uint8_t* buffer, uint32_t length) override;
+ uint32_t get_num_excess() const override { return num_crlf; };
private:
static const int MAX_LEADING_WHITESPACE = 20;
};
class NHttpHeaderSplitter : public NHttpSplitter {
public:
- NHttpEnums::ScanResult split(const uint8_t* buffer, uint32_t length);
- NHttpEnums::ScanResult peek(const uint8_t* buffer, uint32_t length);
- void conditional_reset();
- uint32_t get_octets_seen() const { return octets_seen - peek_octets; };
- uint32_t get_num_excess() const { return num_crlf; };
+ NHttpEnums::ScanResult split(const uint8_t* buffer, uint32_t length) override;
+ NHttpEnums::ScanResult peek(const uint8_t* buffer, uint32_t length) override;
+ void conditional_reset() override;
+ uint32_t get_octets_seen() const override { return octets_seen - peek_octets; };
+ uint32_t get_num_excess() const override { return num_crlf; };
private:
uint32_t peek_octets = 0;
unsigned first_lf = 0;
class NHttpChunkSplitter : public NHttpSplitter {
public:
- NHttpEnums::ScanResult split(const uint8_t* buffer, uint32_t length);
- uint32_t get_num_excess() const { return zero_chunk ? 1 : 0; };
- void conditional_reset();
- bool partial_ok() const { return false; };
+ NHttpEnums::ScanResult split(const uint8_t* buffer, uint32_t length) override;
+ uint32_t get_num_excess() const override { return zero_chunk ? 1 : 0; };
+ void conditional_reset() override;
+ bool partial_ok() const override { return false; };
private:
uint32_t expected_length = 0;
bool length_started = false;
class NHttpTrailerSplitter : public NHttpSplitter {
public:
- NHttpEnums::ScanResult split(const uint8_t* buffer, uint32_t length);
- void conditional_reset();
- uint32_t get_num_excess() const { return num_crlf; };
+ NHttpEnums::ScanResult split(const uint8_t* buffer, uint32_t length) override;
+ void conditional_reset() override;
+ uint32_t get_num_excess() const override { return num_crlf; };
private:
unsigned first_lf = 0;
};