64    protocol_str = 
"HTTP/1.1";
 
   79    for (
auto& ptr : lines){
 
 
   86  HttpHeader& put(
const char* key, 
const char* value) {
 
   87    if (value != 
nullptr && strlen(value) > 0) {
 
   88      LOGD(
"HttpHeader::put %s %s", key, value);
 
   91        if (create_new_lines){
 
   92          LOGE(
"HttpHeader::put - did not add HttpHeaderLine for %s", key);
 
   98      LOGD(
"HttpHeader::put -> '%s' : '%s'", key, value);
 
  104      if (StrView(key).equalsIgnoreCase(TRANSFER_ENCODING) && StrView(value) == CHUNKED) {
 
  105        LOGI(
"- is_chunked!!!");
 
  106        this->is_chunked = 
true;
 
  109      if (StrView(key).equalsIgnoreCase(CONTENT_TYPE)) {
 
  110        LOGI(
"%s: %s", CONTENT_TYPE, value);
 
  113      LOGD(
"HttpHeader::put - value ignored because it is null for %s", key);
 
  120    LOGD(
"HttpHeader::put %s %d", key, value);
 
  124      LOGW(
"value is > 1000");
 
  130    LOGI(
"%s %s", key, hl->value.
c_str());
 
 
  136    LOGD(
"HttpHeader::put -> %s", (
const char*)line);
 
  139    char* key = (
char*)line;
 
  143    const char* value = line + pos + 1;
 
  144    if (value[0] == 
' ') {
 
  145      value = line + pos + 2;
 
  147    return put((
const char*)key, value);
 
 
  151  const char* get(
const char* key) {
 
  152    for (
auto& line_ptr : lines) {
 
  155      line_ptr->key = trimmed.c_str();
 
  157      if (StrView(line_ptr->key.c_str()).equalsIgnoreCase(key)) {
 
  158        const char* result = line_ptr->value.c_str();
 
  159        return line_ptr->active ? result : 
nullptr;
 
  166  int readLine(Client& in, 
char* str, 
int len) {
 
  167    int result = reader.readlnInternal(in, (uint8_t*)str, len, 
false);
 
  168    LOGD(
"HttpHeader::readLine -> %s", str);
 
  173  void writeHeaderLine(Client& out, HttpHeaderLine& header) {
 
  174    LOGD(
"HttpHeader::writeHeaderLine: %s", header.key.c_str());
 
  175    if (!header.active) {
 
  176      LOGD(
"HttpHeader::writeHeaderLine - not active");
 
  179    if (header.value.c_str() == 
nullptr) {
 
  180      LOGD(
"HttpHeader::writeHeaderLine - ignored because value is null");
 
  184    char* msg = tempBuffer();
 
  185    StrView msg_str(msg, HTTP_MAX_LEN);
 
  186    msg_str = header.key.c_str();
 
  188    msg_str += header.value.c_str();
 
  190    out.print(msg_str.c_str());
 
  194    int len = strlen(msg);
 
  196    LOGI(
" -> %s ", msg);
 
  202  const char* urlPath() { 
return url_path.
c_str(); }
 
  204  MethodID method() { 
return method_id; }
 
  206  int statusCode() { 
return status_code; }
 
  208  const char* statusMessage() { 
return status_msg.
c_str(); }
 
  217    LOGD(
"HttpHeader::read");
 
  221    char* line = tempBuffer();
 
  222    if (in.connected()) {
 
  223      if (in.available() == 0) {
 
  225        uint32_t timeout = 
millis() + timeout_ms;
 
  226        while (in.available() == 0) {
 
  230            LOGI(
"Waiting for data...");
 
  234            LOGE(
"Request timed out after %d ms", (
int)timeout_ms);
 
  239        LOGI(
"Data available: %d", in.available());
 
  242      readLine(in, line, HTTP_MAX_LEN);
 
  245        int len = readLine(in, line, HTTP_MAX_LEN);
 
  246        if (len == 0 && in.available() == 0) 
break;
 
 
  262    LOGI(
"HttpHeader::write");
 
  264    for (
auto& line_ptr : lines) {
 
  265      writeHeaderLine(out, *line_ptr);
 
 
  273  void setProcessed() {
 
  274    for (
auto& line :lines) {
 
  275      line->active = 
false;
 
  281    create_new_lines = is_auto_line;
 
 
  291  void end() { temp_buffer.resize(0); }
 
  300  void setProtocol(
const char* protocal) { protocol_str = protocal; }
 
  304    temp_buffer.resize(bufferSize);
 
 
  313  int status_code = UNDEFINED;
 
  314  bool is_written = 
false;
 
  315  bool is_chunked = 
false;
 
  316  bool create_new_lines = 
true;
 
  321  Str protocol_str{10};
 
  324  List<HttpHeaderLine*> lines;
 
  325  HttpLineReader reader;
 
  326  const char* CRLF = 
"\r\n";
 
  327  int timeout_ms = URL_CLIENT_TIMEOUT;
 
  328  Vector<char> temp_buffer{HTTP_MAX_LEN};
 
  332    return temp_buffer.data();
 
  336  void crlf(Client& out) {
 
  338    LOGI(
" -> %s ", 
"<CR LF>");
 
  342  HttpHeaderLine* headerLine(
const char* key) {
 
  343    if (key != 
nullptr) {
 
  344      for (
auto& line_ptr : lines) {
 
  345        if (line_ptr->key.c_str() != 
nullptr) {
 
  346          if (line_ptr->key.equalsIgnoreCase(key)) {
 
  347            line_ptr->active = 
true;
 
  352      if (create_new_lines || StrView(key).equalsIgnoreCase(CONTENT_LENGTH) ||
 
  353          StrView(key).equalsIgnoreCase(CONTENT_TYPE)) {
 
  354        HttpHeaderLine *new_line = 
new HttpHeaderLine(key);    
 
  355        lines.push_back(new_line);
 
  359      LOGI(
"HttpHeader::headerLine %s", 
"The key must not be null");
 
  364  MethodID getMethod(
const char* line) {
 
  366    for (
int j = 0; methods[j] != 
nullptr; j++) {
 
  367      const char* action = methods[j];
 
  368      int len = strlen(action);
 
  369      if (strncmp(action, line, len) == 0) {
 
  376  virtual void write1stLine(Client& out) = 0;
 
  377  virtual void parse1stLine(
const char* line) = 0;
 
 
  388  HttpHeader& setValues(MethodID 
id, 
const char* urlPath,
 
  390    this->method_id = id;
 
  391    this->url_path = urlPath;
 
  393    LOGD(
"HttpRequestHeader::setValues - path: %s", this->url_path.
c_str());
 
  401  void write1stLine(
Client& out) {
 
  402    LOGD(
"HttpRequestHeader::write1stLine");
 
  403    char* msg = tempBuffer();
 
  404    StrView msg_str(msg, HTTP_MAX_LEN);
 
  406    const char* method_str = methods[this->method_id];
 
  407    msg_str = method_str;
 
  409    msg_str += this->url_path.
c_str();
 
  411    msg_str += this->protocol_str.
c_str();
 
  415    int len = strlen(msg);
 
  422  void parse1stLine(
const char* line) {
 
  423    LOGD(
"HttpRequestHeader::parse1stLine %s", line);
 
  425    int space1 = line_str.
indexOf(
" ");
 
  426    int space2 = line_str.
indexOf(
" ", space1 + 1);
 
  428    this->method_id = getMethod(line);
 
  430    this->url_path.
substring(line_str, space1 + 1, space2);
 
  431    this->url_path.
trim();
 
  433    LOGD(
"->method %s", methods[this->method_id]);
 
  434    LOGD(
"->protocol %s", protocol_str.
c_str());
 
  435    LOGD(
"->url_path %s", url_path.
c_str());
 
 
  447  void setValues(
int statusCode, 
const char* msg = 
"",
 
  449    LOGI(
"HttpReplyHeader::setValues");
 
  451    status_code = statusCode;
 
  458  void readExt(
Client& in) {
 
  459    LOGI(
"HttpReplyHeader::readExt");
 
  460    char* line = tempBuffer();
 
  461    readLine(in, line, HTTP_MAX_LEN);
 
  462    while (strlen(line) != 0) {
 
  464      readLine(in, line, HTTP_MAX_LEN);
 
  469  void write1stLine(
Client& out) {
 
  470    LOGI(
"HttpReplyHeader::write1stLine");
 
  471    char* msg = tempBuffer();
 
  472    StrView msg_str(msg, HTTP_MAX_LEN);
 
  473    msg_str = this->protocol_str.
c_str();
 
  475    msg_str += this->status_code;
 
  477    msg_str += this->status_msg.
c_str();
 
  486  void parse1stLine(
const char* line) {
 
  487    LOGD(
"HttpReplyHeader::parse1stLine: %s", line);
 
  489    int space1 = line_str.
indexOf(
' ', 0);
 
  490    int space2 = line_str.
indexOf(
' ', space1 + 1);
 
  493    protocol_str.
substring(line_str, 0, space1);
 
  498    status.
substring(line_str, space1 + 1, space2);
 
  499    status_code = atoi(status_c);