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

Dependencies:   mbed EthernetInterface HTTPClient mbed-rtos

Committer:
va009039
Date:
Thu May 31 10:32:39 2012 +0000
Revision:
0:fcd577a3925b
Child:
1:77c616a1ab54

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:fcd577a3925b 1
va009039 0:fcd577a3925b 2 /*
va009039 0:fcd577a3925b 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
va009039 0:fcd577a3925b 4
va009039 0:fcd577a3925b 5 Permission is hereby granted, free of charge, to any person obtaining a copy
va009039 0:fcd577a3925b 6 of this software and associated documentation files (the "Software"), to deal
va009039 0:fcd577a3925b 7 in the Software without restriction, including without limitation the rights
va009039 0:fcd577a3925b 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
va009039 0:fcd577a3925b 9 copies of the Software, and to permit persons to whom the Software is
va009039 0:fcd577a3925b 10 furnished to do so, subject to the following conditions:
va009039 0:fcd577a3925b 11
va009039 0:fcd577a3925b 12 The above copyright notice and this permission notice shall be included in
va009039 0:fcd577a3925b 13 all copies or substantial portions of the Software.
va009039 0:fcd577a3925b 14
va009039 0:fcd577a3925b 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
va009039 0:fcd577a3925b 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
va009039 0:fcd577a3925b 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
va009039 0:fcd577a3925b 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
va009039 0:fcd577a3925b 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
va009039 0:fcd577a3925b 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
va009039 0:fcd577a3925b 21 THE SOFTWARE.
va009039 0:fcd577a3925b 22 */
va009039 0:fcd577a3925b 23
va009039 0:fcd577a3925b 24 #include "HTTPPoster.h"
va009039 0:fcd577a3925b 25 //#define __DEBUG
va009039 0:fcd577a3925b 26 //#include "mydbg.h"
va009039 0:fcd577a3925b 27 #include "dbg/dbg.h"
va009039 0:fcd577a3925b 28
va009039 0:fcd577a3925b 29 ///HTTP Client data container for form(multipart/form-data)
va009039 0:fcd577a3925b 30 HTTPPoster::HTTPPoster()
va009039 0:fcd577a3925b 31 {
va009039 0:fcd577a3925b 32 DBG("\n");
va009039 0:fcd577a3925b 33 m_cur = 0;
va009039 0:fcd577a3925b 34 m_seq = 0;
va009039 0:fcd577a3925b 35 m_send_len = 0;
va009039 0:fcd577a3925b 36 m_fp = NULL;
va009039 0:fcd577a3925b 37 m_post_data.clear();
va009039 0:fcd577a3925b 38 m_buf.clear();
va009039 0:fcd577a3925b 39 m_boundary = "----mbedHTTPClientPoster";
va009039 0:fcd577a3925b 40 m_ContentType = "multipart/form-data; boundary=";
va009039 0:fcd577a3925b 41 m_ContentType += m_boundary;
va009039 0:fcd577a3925b 42 }
va009039 0:fcd577a3925b 43
va009039 0:fcd577a3925b 44 HTTPPoster::~HTTPPoster()
va009039 0:fcd577a3925b 45 {
va009039 0:fcd577a3925b 46 DBG("m_post_data.size()=%d\n", m_post_data.size());
va009039 0:fcd577a3925b 47 if (m_fp) {
va009039 0:fcd577a3925b 48 fclose(m_fp);
va009039 0:fcd577a3925b 49 m_fp = NULL;
va009039 0:fcd577a3925b 50 }
va009039 0:fcd577a3925b 51 }
va009039 0:fcd577a3925b 52
va009039 0:fcd577a3925b 53 bool HTTPPoster::addFile(const char* name, const char* path)
va009039 0:fcd577a3925b 54 {
va009039 0:fcd577a3925b 55 DBG("%p name=%s path=%s\n", this, name, path);
va009039 0:fcd577a3925b 56 struct stpost data;
va009039 0:fcd577a3925b 57
va009039 0:fcd577a3925b 58 m_fp = fopen(path, "rb");
va009039 0:fcd577a3925b 59 if (m_fp == NULL) {
va009039 0:fcd577a3925b 60 return false;
va009039 0:fcd577a3925b 61 }
va009039 0:fcd577a3925b 62 fseek(m_fp, 0, SEEK_END);
va009039 0:fcd577a3925b 63 data.length = ftell(m_fp);
va009039 0:fcd577a3925b 64 fclose(m_fp);
va009039 0:fcd577a3925b 65
va009039 0:fcd577a3925b 66 string head = "Content-Disposition: form-data; name=\"";
va009039 0:fcd577a3925b 67 head += name;
va009039 0:fcd577a3925b 68 head += "\"; filename=\"";
va009039 0:fcd577a3925b 69 head += path;
va009039 0:fcd577a3925b 70 head += "\"";
va009039 0:fcd577a3925b 71
va009039 0:fcd577a3925b 72 data.head = head;
va009039 0:fcd577a3925b 73 data.value = path;
va009039 0:fcd577a3925b 74 data.file = true;
va009039 0:fcd577a3925b 75 m_post_data.push_back(data);
va009039 0:fcd577a3925b 76 return true;
va009039 0:fcd577a3925b 77 }
va009039 0:fcd577a3925b 78
va009039 0:fcd577a3925b 79 bool HTTPPoster::add(const char* name, const char* value)
va009039 0:fcd577a3925b 80 {
va009039 0:fcd577a3925b 81 DBG("%p name=%s value=%s\n", this, name, value);
va009039 0:fcd577a3925b 82 struct stpost data;
va009039 0:fcd577a3925b 83
va009039 0:fcd577a3925b 84 string head = "Content-Disposition: form-data; name=\"";
va009039 0:fcd577a3925b 85 head += name;
va009039 0:fcd577a3925b 86 head += "\"";
va009039 0:fcd577a3925b 87
va009039 0:fcd577a3925b 88 data.head = head;
va009039 0:fcd577a3925b 89 data.value = value;
va009039 0:fcd577a3925b 90 data.length = strlen(value);
va009039 0:fcd577a3925b 91 data.file = false;
va009039 0:fcd577a3925b 92 m_post_data.push_back(data);
va009039 0:fcd577a3925b 93 return true;
va009039 0:fcd577a3925b 94 }
va009039 0:fcd577a3925b 95
va009039 0:fcd577a3925b 96 int HTTPPoster::read(char* buf, int len)
va009039 0:fcd577a3925b 97 {
va009039 0:fcd577a3925b 98 //DBG("buf=%p len=%d\n", buf, len);
va009039 0:fcd577a3925b 99 int c;
va009039 0:fcd577a3925b 100 switch(m_seq) {
va009039 0:fcd577a3925b 101 case 0:
va009039 0:fcd577a3925b 102 if (m_cur >= m_post_data.size()) {
va009039 0:fcd577a3925b 103 m_buf += "--";
va009039 0:fcd577a3925b 104 m_buf += m_boundary;
va009039 0:fcd577a3925b 105 m_buf += "--\r\n";
va009039 0:fcd577a3925b 106 m_seq = 4; // done
va009039 0:fcd577a3925b 107 } else {
va009039 0:fcd577a3925b 108 m_buf += "--";
va009039 0:fcd577a3925b 109 m_buf += m_boundary;
va009039 0:fcd577a3925b 110 m_buf += "\r\n";
va009039 0:fcd577a3925b 111 m_seq++;
va009039 0:fcd577a3925b 112 }
va009039 0:fcd577a3925b 113 break;
va009039 0:fcd577a3925b 114 case 1:
va009039 0:fcd577a3925b 115 m_buf += m_post_data[m_cur].head;
va009039 0:fcd577a3925b 116 m_buf += "\r\n\r\n";
va009039 0:fcd577a3925b 117 if (m_post_data[m_cur].file) {
va009039 0:fcd577a3925b 118 m_fp = fopen(m_post_data[m_cur].value.c_str(), "rb");
va009039 0:fcd577a3925b 119 }
va009039 0:fcd577a3925b 120 m_pos = 0;
va009039 0:fcd577a3925b 121 m_seq++;
va009039 0:fcd577a3925b 122 break;
va009039 0:fcd577a3925b 123 case 2:
va009039 0:fcd577a3925b 124 for(int i = 0; i < len; i++) {
va009039 0:fcd577a3925b 125 if (m_buf.size() >= len) {
va009039 0:fcd577a3925b 126 break;
va009039 0:fcd577a3925b 127 }
va009039 0:fcd577a3925b 128 if (m_pos >= m_post_data[m_cur].length) {
va009039 0:fcd577a3925b 129 m_seq++;
va009039 0:fcd577a3925b 130 break;
va009039 0:fcd577a3925b 131 }
va009039 0:fcd577a3925b 132 if (m_post_data[m_cur].file) {
va009039 0:fcd577a3925b 133 c = fgetc(m_fp);
va009039 0:fcd577a3925b 134 } else {
va009039 0:fcd577a3925b 135 c = m_post_data[m_cur].value[m_pos];
va009039 0:fcd577a3925b 136 }
va009039 0:fcd577a3925b 137 m_buf += (char)c;
va009039 0:fcd577a3925b 138 m_pos++;
va009039 0:fcd577a3925b 139 }
va009039 0:fcd577a3925b 140 break;
va009039 0:fcd577a3925b 141 case 3:
va009039 0:fcd577a3925b 142 m_buf += "\r\n";
va009039 0:fcd577a3925b 143 if (m_fp) {
va009039 0:fcd577a3925b 144 fclose(m_fp);
va009039 0:fcd577a3925b 145 m_fp = NULL;
va009039 0:fcd577a3925b 146 }
va009039 0:fcd577a3925b 147 m_cur++;
va009039 0:fcd577a3925b 148 m_seq = 0;
va009039 0:fcd577a3925b 149 break;
va009039 0:fcd577a3925b 150 default: // done
va009039 0:fcd577a3925b 151 break;
va009039 0:fcd577a3925b 152 }
va009039 0:fcd577a3925b 153 int len2 = m_buf.size();
va009039 0:fcd577a3925b 154 if (len2 > len) {
va009039 0:fcd577a3925b 155 len2 = len;
va009039 0:fcd577a3925b 156 }
va009039 0:fcd577a3925b 157 memcpy(buf, m_buf.data(), len2);
va009039 0:fcd577a3925b 158 m_buf.erase(0, len2);
va009039 0:fcd577a3925b 159 m_send_len += len2;
va009039 0:fcd577a3925b 160 DBG("m_len=%d m_send_len=%d len=%d len2=%d\n", m_len, m_send_len, len, len2);
va009039 0:fcd577a3925b 161 //DBG_HEX((uint8_t*)buf, len2);
va009039 0:fcd577a3925b 162 return len2;
va009039 0:fcd577a3925b 163 }
va009039 0:fcd577a3925b 164
va009039 0:fcd577a3925b 165 string HTTPPoster::getDataType() //Internet media type for Content-Type header
va009039 0:fcd577a3925b 166 {
va009039 0:fcd577a3925b 167 DBG("%s\n", m_ContentType.c_str());
va009039 0:fcd577a3925b 168 return m_ContentType;
va009039 0:fcd577a3925b 169 }
va009039 0:fcd577a3925b 170
va009039 0:fcd577a3925b 171 int 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 DBG("%d m_len=%d\n", i, m_len);
va009039 0:fcd577a3925b 181 }
va009039 0:fcd577a3925b 182 m_len += 2 + strlen(m_boundary) + 2 + 2; // "--" boundary "--" CRLF
va009039 0:fcd577a3925b 183 return m_len;
va009039 0:fcd577a3925b 184 }