HTTP Client data container for form(multipart/form-data)

Dependencies:   mbed EthernetInterface HTTPClient mbed-rtos

Committer:
va009039
Date:
Tue Aug 28 14:39:29 2012 +0000
Revision:
1:77c616a1ab54
Parent:
0:fcd577a3925b
update to using new HTTPClient

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 1:77c616a1ab54 1 /* HTTPPoster.cpp */
va009039 0:fcd577a3925b 2
va009039 1:77c616a1ab54 3 //Debug is disabled by default
va009039 1:77c616a1ab54 4 #if 1
va009039 1:77c616a1ab54 5 //Enable debug
va009039 1:77c616a1ab54 6 #include <cstdio>
va009039 1:77c616a1ab54 7 #define DBG(x, ...) std::printf("[HTTPPoster : DBG]"x"\r\n", ##__VA_ARGS__);
va009039 1:77c616a1ab54 8 //#define DBG(x, ...)
va009039 1:77c616a1ab54 9 #define WARN(x, ...) std::printf("[HTTPPoster : WARN]"x"\r\n", ##__VA_ARGS__);
va009039 1:77c616a1ab54 10 #define ERR(x, ...) std::printf("[HTTPPoster : ERR]"x"\r\n", ##__VA_ARGS__);
va009039 1:77c616a1ab54 11
va009039 1:77c616a1ab54 12 #else
va009039 1:77c616a1ab54 13 //Disable debug
va009039 1:77c616a1ab54 14 #define DBG(x, ...)
va009039 1:77c616a1ab54 15 #define WARN(x, ...)
va009039 1:77c616a1ab54 16 #define ERR(x, ...)
va009039 1:77c616a1ab54 17
va009039 1:77c616a1ab54 18 #endif
va009039 0:fcd577a3925b 19
va009039 0:fcd577a3925b 20 #include "HTTPPoster.h"
va009039 1:77c616a1ab54 21
va009039 1:77c616a1ab54 22 #define OK 0
va009039 0:fcd577a3925b 23
va009039 0:fcd577a3925b 24 ///HTTP Client data container for form(multipart/form-data)
va009039 0:fcd577a3925b 25 HTTPPoster::HTTPPoster()
va009039 0:fcd577a3925b 26 {
va009039 0:fcd577a3925b 27 m_cur = 0;
va009039 0:fcd577a3925b 28 m_seq = 0;
va009039 0:fcd577a3925b 29 m_send_len = 0;
va009039 0:fcd577a3925b 30 m_fp = NULL;
va009039 0:fcd577a3925b 31 m_post_data.clear();
va009039 0:fcd577a3925b 32 m_buf.clear();
va009039 1:77c616a1ab54 33 m_boundary = "----HTTPPoster123";
va009039 0:fcd577a3925b 34 m_ContentType = "multipart/form-data; boundary=";
va009039 0:fcd577a3925b 35 m_ContentType += m_boundary;
va009039 0:fcd577a3925b 36 }
va009039 0:fcd577a3925b 37
va009039 0:fcd577a3925b 38 HTTPPoster::~HTTPPoster()
va009039 0:fcd577a3925b 39 {
va009039 0:fcd577a3925b 40 if (m_fp) {
va009039 0:fcd577a3925b 41 fclose(m_fp);
va009039 0:fcd577a3925b 42 m_fp = NULL;
va009039 0:fcd577a3925b 43 }
va009039 0:fcd577a3925b 44 }
va009039 0:fcd577a3925b 45
va009039 0:fcd577a3925b 46 bool HTTPPoster::addFile(const char* name, const char* path)
va009039 0:fcd577a3925b 47 {
va009039 0:fcd577a3925b 48 struct stpost data;
va009039 0:fcd577a3925b 49
va009039 0:fcd577a3925b 50 m_fp = fopen(path, "rb");
va009039 0:fcd577a3925b 51 if (m_fp == NULL) {
va009039 0:fcd577a3925b 52 return false;
va009039 0:fcd577a3925b 53 }
va009039 0:fcd577a3925b 54 fseek(m_fp, 0, SEEK_END);
va009039 0:fcd577a3925b 55 data.length = ftell(m_fp);
va009039 0:fcd577a3925b 56 fclose(m_fp);
va009039 0:fcd577a3925b 57
va009039 0:fcd577a3925b 58 string head = "Content-Disposition: form-data; name=\"";
va009039 0:fcd577a3925b 59 head += name;
va009039 0:fcd577a3925b 60 head += "\"; filename=\"";
va009039 0:fcd577a3925b 61 head += path;
va009039 0:fcd577a3925b 62 head += "\"";
va009039 0:fcd577a3925b 63
va009039 0:fcd577a3925b 64 data.head = head;
va009039 0:fcd577a3925b 65 data.value = path;
va009039 0:fcd577a3925b 66 data.file = true;
va009039 0:fcd577a3925b 67 m_post_data.push_back(data);
va009039 0:fcd577a3925b 68 return true;
va009039 0:fcd577a3925b 69 }
va009039 0:fcd577a3925b 70
va009039 0:fcd577a3925b 71 bool HTTPPoster::add(const char* name, const char* value)
va009039 0:fcd577a3925b 72 {
va009039 0:fcd577a3925b 73 struct stpost data;
va009039 0:fcd577a3925b 74
va009039 0:fcd577a3925b 75 string head = "Content-Disposition: form-data; name=\"";
va009039 0:fcd577a3925b 76 head += name;
va009039 0:fcd577a3925b 77 head += "\"";
va009039 0:fcd577a3925b 78
va009039 0:fcd577a3925b 79 data.head = head;
va009039 0:fcd577a3925b 80 data.value = value;
va009039 0:fcd577a3925b 81 data.length = strlen(value);
va009039 0:fcd577a3925b 82 data.file = false;
va009039 0:fcd577a3925b 83 m_post_data.push_back(data);
va009039 0:fcd577a3925b 84 return true;
va009039 0:fcd577a3925b 85 }
va009039 0:fcd577a3925b 86
va009039 1:77c616a1ab54 87 /*virtual*/ int HTTPPoster::read(char* buf, size_t len, size_t* pReadLen)
va009039 0:fcd577a3925b 88 {
va009039 0:fcd577a3925b 89 int c;
va009039 0:fcd577a3925b 90 switch(m_seq) {
va009039 0:fcd577a3925b 91 case 0:
va009039 0:fcd577a3925b 92 if (m_cur >= m_post_data.size()) {
va009039 0:fcd577a3925b 93 m_buf += "--";
va009039 0:fcd577a3925b 94 m_buf += m_boundary;
va009039 0:fcd577a3925b 95 m_buf += "--\r\n";
va009039 0:fcd577a3925b 96 m_seq = 4; // done
va009039 0:fcd577a3925b 97 } else {
va009039 0:fcd577a3925b 98 m_buf += "--";
va009039 0:fcd577a3925b 99 m_buf += m_boundary;
va009039 0:fcd577a3925b 100 m_buf += "\r\n";
va009039 0:fcd577a3925b 101 m_seq++;
va009039 0:fcd577a3925b 102 }
va009039 0:fcd577a3925b 103 break;
va009039 0:fcd577a3925b 104 case 1:
va009039 0:fcd577a3925b 105 m_buf += m_post_data[m_cur].head;
va009039 0:fcd577a3925b 106 m_buf += "\r\n\r\n";
va009039 0:fcd577a3925b 107 if (m_post_data[m_cur].file) {
va009039 0:fcd577a3925b 108 m_fp = fopen(m_post_data[m_cur].value.c_str(), "rb");
va009039 0:fcd577a3925b 109 }
va009039 0:fcd577a3925b 110 m_pos = 0;
va009039 0:fcd577a3925b 111 m_seq++;
va009039 0:fcd577a3925b 112 break;
va009039 0:fcd577a3925b 113 case 2:
va009039 0:fcd577a3925b 114 for(int i = 0; i < len; i++) {
va009039 0:fcd577a3925b 115 if (m_buf.size() >= len) {
va009039 0:fcd577a3925b 116 break;
va009039 0:fcd577a3925b 117 }
va009039 0:fcd577a3925b 118 if (m_pos >= m_post_data[m_cur].length) {
va009039 0:fcd577a3925b 119 m_seq++;
va009039 0:fcd577a3925b 120 break;
va009039 0:fcd577a3925b 121 }
va009039 0:fcd577a3925b 122 if (m_post_data[m_cur].file) {
va009039 0:fcd577a3925b 123 c = fgetc(m_fp);
va009039 0:fcd577a3925b 124 } else {
va009039 0:fcd577a3925b 125 c = m_post_data[m_cur].value[m_pos];
va009039 0:fcd577a3925b 126 }
va009039 0:fcd577a3925b 127 m_buf += (char)c;
va009039 0:fcd577a3925b 128 m_pos++;
va009039 0:fcd577a3925b 129 }
va009039 0:fcd577a3925b 130 break;
va009039 0:fcd577a3925b 131 case 3:
va009039 0:fcd577a3925b 132 m_buf += "\r\n";
va009039 0:fcd577a3925b 133 if (m_fp) {
va009039 0:fcd577a3925b 134 fclose(m_fp);
va009039 0:fcd577a3925b 135 m_fp = NULL;
va009039 0:fcd577a3925b 136 }
va009039 0:fcd577a3925b 137 m_cur++;
va009039 0:fcd577a3925b 138 m_seq = 0;
va009039 0:fcd577a3925b 139 break;
va009039 0:fcd577a3925b 140 default: // done
va009039 0:fcd577a3925b 141 break;
va009039 0:fcd577a3925b 142 }
va009039 0:fcd577a3925b 143 int len2 = m_buf.size();
va009039 0:fcd577a3925b 144 if (len2 > len) {
va009039 0:fcd577a3925b 145 len2 = len;
va009039 0:fcd577a3925b 146 }
va009039 0:fcd577a3925b 147 memcpy(buf, m_buf.data(), len2);
va009039 0:fcd577a3925b 148 m_buf.erase(0, len2);
va009039 0:fcd577a3925b 149 m_send_len += len2;
va009039 1:77c616a1ab54 150 DBG("m_len=%d m_send_len=%d len=%d len2=%d", m_len, m_send_len, len, len2);
va009039 1:77c616a1ab54 151 *pReadLen = len2;
va009039 1:77c616a1ab54 152 return OK;
va009039 0:fcd577a3925b 153 }
va009039 0:fcd577a3925b 154
va009039 1:77c616a1ab54 155 /*virtual*/ int HTTPPoster::getDataType(char* type, size_t maxTypeLen) //Internet media type for Content-Type header
va009039 0:fcd577a3925b 156 {
va009039 1:77c616a1ab54 157 if (m_ContentType.length() >= maxTypeLen) {
va009039 1:77c616a1ab54 158 WARN("maxTypeLen=%d", maxTypeLen);
va009039 1:77c616a1ab54 159 WARN("m_ContentType.length()=%d", m_ContentType.length());
va009039 1:77c616a1ab54 160 return !OK;
va009039 1:77c616a1ab54 161 }
va009039 1:77c616a1ab54 162 strcpy(type, m_ContentType.c_str());
va009039 1:77c616a1ab54 163 return OK;
va009039 0:fcd577a3925b 164 }
va009039 0:fcd577a3925b 165
va009039 1:77c616a1ab54 166 /*virtual*/ bool HTTPPoster::getIsChunked() //For Transfer-Encoding header
va009039 1:77c616a1ab54 167 {
va009039 1:77c616a1ab54 168 return false; ////Data is computed one key/value pair at a time
va009039 1:77c616a1ab54 169 }
va009039 1:77c616a1ab54 170
va009039 1:77c616a1ab54 171 /*virtual*/ size_t HTTPPoster::getDataLen() //For Content-Length header
va009039 0:fcd577a3925b 172 {
va009039 0:fcd577a3925b 173 m_len = 0;
va009039 0:fcd577a3925b 174 for(int i = 0; i < m_post_data.size(); i++) {
va009039 0:fcd577a3925b 175 m_len += 2 + strlen(m_boundary) + 2; // "--" boundary CRLF
va009039 0:fcd577a3925b 176 m_len += m_post_data[i].head.size() + 2; // Content-Disposition: ... CRLF
va009039 0:fcd577a3925b 177 m_len += 2; // CRLF
va009039 0:fcd577a3925b 178 m_len += m_post_data[i].length; // value / file body
va009039 0:fcd577a3925b 179 m_len += 2; // CRLF
va009039 0:fcd577a3925b 180 }
va009039 0:fcd577a3925b 181 m_len += 2 + strlen(m_boundary) + 2 + 2; // "--" boundary "--" CRLF
va009039 0:fcd577a3925b 182 return m_len;
va009039 0:fcd577a3925b 183 }