HTTP Client data container for form(multipart/form-data)
Dependencies: mbed EthernetInterface HTTPClient mbed-rtos
Diff: HTTPPoster.cpp
- Revision:
- 0:fcd577a3925b
- Child:
- 1:77c616a1ab54
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HTTPPoster.cpp Thu May 31 10:32:39 2012 +0000 @@ -0,0 +1,184 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "HTTPPoster.h" +//#define __DEBUG +//#include "mydbg.h" +#include "dbg/dbg.h" + +///HTTP Client data container for form(multipart/form-data) +HTTPPoster::HTTPPoster() +{ + DBG("\n"); + m_cur = 0; + m_seq = 0; + m_send_len = 0; + m_fp = NULL; + m_post_data.clear(); + m_buf.clear(); + m_boundary = "----mbedHTTPClientPoster"; + m_ContentType = "multipart/form-data; boundary="; + m_ContentType += m_boundary; +} + +HTTPPoster::~HTTPPoster() +{ + DBG("m_post_data.size()=%d\n", m_post_data.size()); + if (m_fp) { + fclose(m_fp); + m_fp = NULL; + } +} + +bool HTTPPoster::addFile(const char* name, const char* path) +{ + DBG("%p name=%s path=%s\n", this, name, 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) +{ + DBG("%p name=%s value=%s\n", this, name, 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; +} + +int HTTPPoster::read(char* buf, int len) +{ + //DBG("buf=%p len=%d\n", buf, len); + 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\n", m_len, m_send_len, len, len2); + //DBG_HEX((uint8_t*)buf, len2); + return len2; +} + +string HTTPPoster::getDataType() //Internet media type for Content-Type header +{ + DBG("%s\n", m_ContentType.c_str()); + return m_ContentType; +} + +int 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 + DBG("%d m_len=%d\n", i, m_len); + } + m_len += 2 + strlen(m_boundary) + 2 + 2; // "--" boundary "--" CRLF + return m_len; +}