HTTP Client data container for form(multipart/form-data)
Dependencies: mbed EthernetInterface HTTPClient mbed-rtos
HTTPPoster.cpp
- Committer:
- va009039
- Date:
- 2012-08-28
- Revision:
- 1:77c616a1ab54
- Parent:
- 0:fcd577a3925b
File content as of revision 1:77c616a1ab54:
/* HTTPPoster.cpp */ //Debug is disabled by default #if 1 //Enable debug #include <cstdio> #define DBG(x, ...) std::printf("[HTTPPoster : DBG]"x"\r\n", ##__VA_ARGS__); //#define DBG(x, ...) #define WARN(x, ...) std::printf("[HTTPPoster : WARN]"x"\r\n", ##__VA_ARGS__); #define ERR(x, ...) std::printf("[HTTPPoster : ERR]"x"\r\n", ##__VA_ARGS__); #else //Disable debug #define DBG(x, ...) #define WARN(x, ...) #define ERR(x, ...) #endif #include "HTTPPoster.h" #define OK 0 ///HTTP Client data container for form(multipart/form-data) HTTPPoster::HTTPPoster() { m_cur = 0; m_seq = 0; m_send_len = 0; m_fp = NULL; m_post_data.clear(); m_buf.clear(); m_boundary = "----HTTPPoster123"; m_ContentType = "multipart/form-data; boundary="; m_ContentType += m_boundary; } HTTPPoster::~HTTPPoster() { if (m_fp) { fclose(m_fp); m_fp = NULL; } } bool HTTPPoster::addFile(const char* name, const char* path) { struct stpost data; m_fp = fopen(path, "rb"); if (m_fp == NULL) { return false; } fseek(m_fp, 0, SEEK_END); data.length = ftell(m_fp); fclose(m_fp); string head = "Content-Disposition: form-data; name=\""; head += name; head += "\"; filename=\""; head += path; head += "\""; data.head = head; data.value = path; data.file = true; m_post_data.push_back(data); return true; } bool HTTPPoster::add(const char* name, const char* value) { struct stpost data; string head = "Content-Disposition: form-data; name=\""; head += name; head += "\""; data.head = head; data.value = value; data.length = strlen(value); data.file = false; m_post_data.push_back(data); return true; } /*virtual*/ int HTTPPoster::read(char* buf, size_t len, size_t* pReadLen) { int c; switch(m_seq) { case 0: if (m_cur >= m_post_data.size()) { m_buf += "--"; m_buf += m_boundary; m_buf += "--\r\n"; m_seq = 4; // done } else { m_buf += "--"; m_buf += m_boundary; m_buf += "\r\n"; m_seq++; } break; case 1: m_buf += m_post_data[m_cur].head; m_buf += "\r\n\r\n"; if (m_post_data[m_cur].file) { m_fp = fopen(m_post_data[m_cur].value.c_str(), "rb"); } m_pos = 0; m_seq++; break; case 2: for(int i = 0; i < len; i++) { if (m_buf.size() >= len) { break; } if (m_pos >= m_post_data[m_cur].length) { m_seq++; break; } if (m_post_data[m_cur].file) { c = fgetc(m_fp); } else { c = m_post_data[m_cur].value[m_pos]; } m_buf += (char)c; m_pos++; } break; case 3: m_buf += "\r\n"; if (m_fp) { fclose(m_fp); m_fp = NULL; } m_cur++; m_seq = 0; break; default: // done break; } int len2 = m_buf.size(); if (len2 > len) { len2 = len; } memcpy(buf, m_buf.data(), len2); m_buf.erase(0, len2); m_send_len += len2; DBG("m_len=%d m_send_len=%d len=%d len2=%d", m_len, m_send_len, len, len2); *pReadLen = len2; return OK; } /*virtual*/ int HTTPPoster::getDataType(char* type, size_t maxTypeLen) //Internet media type for Content-Type header { if (m_ContentType.length() >= maxTypeLen) { WARN("maxTypeLen=%d", maxTypeLen); WARN("m_ContentType.length()=%d", m_ContentType.length()); return !OK; } strcpy(type, m_ContentType.c_str()); return OK; } /*virtual*/ bool HTTPPoster::getIsChunked() //For Transfer-Encoding header { return false; ////Data is computed one key/value pair at a time } /*virtual*/ size_t HTTPPoster::getDataLen() //For Content-Length header { m_len = 0; for(int i = 0; i < m_post_data.size(); i++) { m_len += 2 + strlen(m_boundary) + 2; // "--" boundary CRLF m_len += m_post_data[i].head.size() + 2; // Content-Disposition: ... CRLF m_len += 2; // CRLF m_len += m_post_data[i].length; // value / file body m_len += 2; // CRLF } m_len += 2 + strlen(m_boundary) + 2 + 2; // "--" boundary "--" CRLF return m_len; }