Use this library to upload images to twitpic.com. The library creates and uses its own TCPSocket. Requires EthernetNetIf and DNSResolver. (this library actually designed by a friend of mine, novachild, with no mbed license of his own.)

Dependents:   TwitPicExample

Files at this revision

API Documentation at this revision

Comitter:
treebykooba
Date:
Sat Feb 26 20:07:01 2011 +0000
Commit message:

Changed in this revision

TwitPic.cpp Show annotated file Show diff for this revision Revisions of this file
TwitPic.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r e8e33b39c3cc TwitPic.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TwitPic.cpp	Sat Feb 26 20:07:01 2011 +0000
@@ -0,0 +1,556 @@
+/*
+  TwitPic.cpp - TwitPic Image Uploader for mbed
+  Copyright (c) novachild 2011. All right reserved.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+*/
+
+#include "TwitPic.h"
+#include "string.h"
+
+#define MIN(a, b)  (a < b ? a : b)
+#define MAX(a, b)  (a > b ? a : b)
+
+#define SENDING_BUFFER_SIZE 4096 //must be large enough to hold all parameters: I wouldn't go under 2 KB.
+#define RECEIVING_BUFFER_SIZE 1024 //for holding respones (early ones will be discared, 1KB should do)
+#define SENDING_CHUNK_SIZE 1024 //amount to send over the socket at once.
+
+#define TWITPIC_URL                     "api.twitpic.com"
+#define TWITPIC_UPLOAD_API_URL            "/1/upload.xml"
+#define TWITPIC_UPLOAD_AND_POST_API_URL "/1/uploadAndPost.xml"
+
+#define BOUNDARY                        "----------0dcb31395642"
+#define HEADER                            "--" BOUNDARY
+#define FOOTER                            "--" BOUNDARY "--"
+
+#define DEBUG 1
+#define TRACE 1
+
+
+const char* m_twitpic_api_key; //twitpic API key
+const char* m_consumer_key; //Consumer key
+const char* m_consumer_secret; //Consumer secret
+const char* m_access_token; //Access Token
+const char* m_access_token_secret; //Access Token secret
+const char* twitterMessage;
+
+bool post = false;
+
+bool sentHeaders = false;
+bool sentParameters = false;
+bool sentImageData = false;
+bool sentFooter = false;
+bool finishedSending = false;
+
+bool positiveResponse = false;
+bool readyToReturn = false;
+bool stillPolling = false;
+
+char sendBuf[SENDING_BUFFER_SIZE];
+char recvBuf[RECEIVING_BUFFER_SIZE];
+
+int imgSize=0;
+int writing_position = 0;
+int errorCode = 0;
+int preCalcedContentLength=0;
+
+int totalSentData=0;
+
+FILE *imgFile;
+
+
+TwitPic::TwitPic(const char *twitpic_api_key, const char *consumer_key, const char *consumer_secret, const char *access_token, const char *access_token_secret) {
+
+    m_twitpic_api_key = twitpic_api_key;
+    m_consumer_key = consumer_key;
+    m_consumer_secret = consumer_secret;
+    m_access_token = access_token;
+    m_access_token_secret = access_token_secret;
+    socket.setOnEvent(this, &TwitPic::handleTCPSocketEvents);
+
+    preCalcedContentLength =  7 * (sizeof(HEADER)-1) +
+                              24* (sizeof("\r\n")-1) +
+                              6 * (sizeof("Content-Disposition: form-data; name=\"") - 1) +
+                              sizeof("key") +
+                              sizeof("consumer_token") +
+                              sizeof("consumer_secret") +
+                              sizeof("oauth_token")  +
+                              sizeof("oauth_secret")  +
+                              sizeof("message") +
+                              strlen(m_twitpic_api_key) +
+                              strlen(m_consumer_key) +
+                              strlen(m_consumer_secret) +
+                              strlen(m_access_token) +
+                              strlen(m_access_token_secret) +
+                              sizeof("\r\nContent-Disposition: form-data; name=\"media\"; filename=\"image.jpg\"\r\n")-1 +
+                              sizeof("Content-Type: image/jpeg\r\n")-1 +
+                              sizeof("Content-Transfer-Encoding: binary\r\n\r\n")-1 +
+                              sizeof("\r\n")-1 +
+                              sizeof(FOOTER) - 1 +
+                              sizeof("\r\n") - 1;
+                             
+}
+
+int TwitPic::upload(const char *message,
+                    FILE *img,
+                    bool toPost) {
+
+    if (TRACE) printf("-----------------------TRACE: upload\n");
+    post = toPost;
+    imgFile = img;
+    twitterMessage = message;
+
+    DNSResolver resolver;
+    server.setIp(resolver.resolveName("api.twitpic.com"));
+    server.setPort(80);
+
+    //Calculate image size
+    fseek (imgFile , 0 , SEEK_END);
+    imgSize = ftell (img);
+    rewind (imgFile);
+
+
+
+    sentHeaders = false;
+    sentParameters = false;
+    sentImageData = false;
+    sentFooter = false;
+    positiveResponse = false;
+    finishedSending = false;
+    readyToReturn = false;
+    writing_position = 0;
+
+    if (DEBUG) printf("Opening connection to api.twitpic.com\n");
+    TCPSocketErr err = socket.connect(server);
+    if (err < 0) {
+        if (DEBUG) printf("Error connecting socket: %i",err);
+        return err;
+    }
+
+    if (DEBUG) printf("Beginning network polling cycle.\n");
+    int countAfterSent = 0;
+    while (! readyToReturn) {
+        if (TRACE && !stillPolling) printf("-----------------------TRACE: Net::poll()\n");
+        stillPolling = true;
+        Net::poll();
+        if (finishedSending) countAfterSent++;
+        if (countAfterSent > 1000000) {
+            if (DEBUG) printf("Polled 1000000 times and got no response. Quitting.\n");
+            positiveResponse = false;
+            readyToReturn = true;
+        }
+    }
+
+    if (positiveResponse) {
+        printf("Image uploaded.\n");
+        return 0;
+    } else {
+        printf("Image not successfully uploaded\n");
+        return errorCode;
+    }
+
+}
+
+int TwitPic::uploadAndPost(const char *message,
+                           FILE *imgFile) {
+    return upload(message, imgFile, true);
+}
+
+void TwitPic::handleTCPSocketEvents(TCPSocketEvent ev) {
+    stillPolling = false;
+    if (TRACE) printf("-----------------------TRACE: handleTCPSocketEvent\n");
+    switch (ev) {
+        case TCPSOCKET_ERROR:
+            printf("-----TCPSocket: Unknown Error\n");
+            goto error;
+        case TCPSOCKET_CONABRT:
+            printf("-----TCPSocket: Connection aborted.\n");
+            goto error;
+        case TCPSOCKET_CONRST:
+            printf("-----TCPSocket: Connection reset.\n");
+            goto error;
+        case TCPSOCKET_CONTIMEOUT:
+            printf("-----TCPSocket: Connection timed out.\n");
+            goto error;
+        case TCPSOCKET_DISCONNECTED:
+            printf("-----TCPSocket: Connection disconnected.\n");
+error:
+            readyToReturn = true;
+            errorCode = ev;
+            positiveResponse = false;
+            break;
+        case TCPSOCKET_CONNECTED:
+            if (DEBUG) printf("-----TCPSocket: Connected.\r\n");
+            sendNextChunk();
+            break;
+        case TCPSOCKET_READABLE:
+            if (DEBUG) printf("-----TCPSocket: Readable.\r\n");
+            getResponse();
+            break;
+        case TCPSOCKET_WRITEABLE:
+            if (DEBUG) printf("-----TCPSOCKET: Writeable.\r\n");
+            if (writing_position < SENDING_BUFFER_SIZE) {
+                if (!sentHeaders) {
+                    sendHeaders();
+                } else if (!sentParameters) {
+                    sendParameters();
+                } else if (!sentImageData) {
+                    sendImageData();
+                } else if (!sentFooter) {
+                    sendFooter();
+                }
+            }
+            if (writing_position > 0) sendNextChunk();
+    }
+}
+
+void TwitPic::sendHeaders() {
+    char* positionPointer;
+    char imgSizeAsString[25];
+    int neededSize = 0;
+    int availableSize = 0;
+
+    if (TRACE) printf("-----------------------TRACE: sendHeaders\n");
+
+    sprintf(imgSizeAsString,"%i",preCalcedContentLength + +strlen(twitterMessage) + imgSize);
+
+    if (post) {
+        neededSize = sizeof(TWITPIC_UPLOAD_AND_POST_API_URL) -1;
+    } else {
+        neededSize = sizeof(TWITPIC_UPLOAD_API_URL)-1;
+    }
+    neededSize +=     sizeof("POST ") -1 +
+                      sizeof(" HTTP/1.0\r\n")-1 +
+                      sizeof("Content-Type: multipart/form-data; boundary=")-1 +
+                      sizeof(BOUNDARY)-1 +
+                      sizeof("\r\nContent-Length: ") - 1 +
+                      strlen(imgSizeAsString) +
+                      sizeof("\r\nExpect: 100-continue") -1 +
+                      sizeof("\r\nHost: api.twitpic.com") - 1 +
+                      sizeof("\r\n\r\n") - 1;
+
+    availableSize = SENDING_BUFFER_SIZE - writing_position;
+
+
+    //for this guy, only add to sendBuf if you can add everything
+    if (availableSize < neededSize) return;
+
+    positionPointer = sendBuf;
+    positionPointer += writing_position;
+    strcpy(positionPointer, "POST ");
+    positionPointer += 5;
+    if (post) {
+        strcpy(positionPointer, TWITPIC_UPLOAD_AND_POST_API_URL);
+        positionPointer += sizeof(TWITPIC_UPLOAD_AND_POST_API_URL)-1;
+    } else {
+        strcpy(positionPointer, TWITPIC_UPLOAD_API_URL);
+        positionPointer += sizeof(TWITPIC_UPLOAD_API_URL)-1;
+    }
+    strcpy(positionPointer, " HTTP/1.1\r\n");
+    positionPointer += 11;
+    strcpy(positionPointer, "Host: api.twitpic.com\r\n");
+    positionPointer+= sizeof("Host: api.twitpic.com\r\n")-1;
+    strcpy(positionPointer, "Content-Length: ");
+    positionPointer += sizeof("Content-Length: ") - 1;
+    strcpy(positionPointer, imgSizeAsString);
+    positionPointer += strlen(imgSizeAsString);
+    strcpy(positionPointer,"\r\nExpect: 100-continue");
+    positionPointer+=sizeof("\r\nExpect: 100-continue")-1;
+    strcpy(positionPointer, "\r\nContent-Type: multipart/form-data; boundary=");
+    positionPointer += sizeof("\r\nContent-Type: multipart/form-data; boundary=")-1;
+    strcpy(positionPointer, BOUNDARY);
+    positionPointer += sizeof(BOUNDARY)-1;
+    strcpy(positionPointer, "\r\n\r\n");
+    positionPointer += 4;
+
+    writing_position += neededSize;
+    if (DEBUG) printf("Wrote headers to buffer. Size = %i\n. Image size reported: %s\n",neededSize, imgSizeAsString);
+    sentHeaders = true;
+}
+
+void TwitPic::sendParameters() {
+    char* positionPointer;
+    int neededSize = 0;
+    int availableSize = 0;
+    int actualsize = 0;
+    char headerline[] = "Content-Disposition: form-data; name=\"";
+
+    if (TRACE) printf("-----------------------TRACE: sendParameters\n");
+    neededSize = 7 * (sizeof(HEADER)-1) +
+                 24* (sizeof("\r\n")-1) +
+                 6 * (sizeof(headerline) - 1) +
+                 sizeof("key") +
+                 sizeof("consumer_token") +
+                 sizeof("consumer_secret") +
+                 sizeof("oauth_token") +
+                 sizeof("oauth_secret") +
+                 sizeof("message") +
+                 strlen(m_twitpic_api_key) +
+                 strlen(m_consumer_key) +
+                 strlen(m_consumer_secret) +
+                 strlen(m_access_token) +
+                 strlen(m_access_token_secret) +
+                 strlen(twitterMessage) +
+                 sizeof("\r\nContent-Disposition: form-data; name=\"media\"; filename=\"image.jpg\"\r\n")-1 +
+                 sizeof("Content-Type: image/jpeg\r\n")-1 +
+                 sizeof("Content-Transfer-Encoding: binary\r\n\r\n")-1;
+
+
+    availableSize = SENDING_BUFFER_SIZE - writing_position;
+
+
+    //for this guy, only add to sendBuf if you can add everything
+    if (availableSize < neededSize) return;
+
+    positionPointer = sendBuf;
+    positionPointer+=writing_position;
+
+    //API Key
+    strcpy(positionPointer, HEADER);
+    positionPointer += sizeof(HEADER)-1;
+    actualsize += sizeof(HEADER) -1;
+    strcpy(positionPointer, "\r\n");
+    positionPointer += 2;
+    actualsize += 2;
+
+    strcpy(positionPointer, headerline);
+    positionPointer += strlen(headerline);
+    actualsize += strlen(headerline);
+    strcpy(positionPointer, "key\"\r\n\r\n");
+    positionPointer += sizeof("key\"\r\n\r\n")-1;
+    actualsize += sizeof("key\"\r\n\r\n")-1;
+    strcpy(positionPointer, m_twitpic_api_key);
+    positionPointer += strlen(m_twitpic_api_key);
+    actualsize +=strlen(m_twitpic_api_key);
+    strcpy(positionPointer, "\r\n");
+    positionPointer+=2;
+    actualsize +=2;
+    //Consumer Key
+    strcpy(positionPointer, HEADER);
+    positionPointer += sizeof(HEADER)-1;
+    actualsize += sizeof(HEADER) -1;
+    strcpy(positionPointer, "\r\n");
+    positionPointer += 2;
+    actualsize += 2;
+
+    strcpy(positionPointer, headerline);
+    positionPointer += strlen(headerline);
+    actualsize += strlen(headerline);
+    strcpy(positionPointer, "consumer_token\"\r\n\r\n");
+    positionPointer += sizeof("consumer_token\"\r\n\r\n")-1;
+    actualsize += sizeof("consumer_token\"\r\n\r\n")-1;
+    strcpy(positionPointer, m_consumer_key);
+    positionPointer += strlen(m_consumer_key);
+    actualsize += strlen(m_consumer_key);
+    strcpy(positionPointer, "\r\n");
+    positionPointer+=2;
+    actualsize+=2;
+
+    //Consumer Secret
+    strcpy(positionPointer, HEADER);
+    positionPointer += sizeof(HEADER)-1;
+    actualsize += sizeof(HEADER) -1;
+    strcpy(positionPointer, "\r\n");
+    positionPointer += 2;
+    actualsize += 2;
+
+    strcpy(positionPointer, headerline);
+    positionPointer += strlen(headerline);
+    actualsize += strlen(headerline);
+    strcpy(positionPointer, "consumer_secret\"\r\n\r\n");
+    positionPointer += sizeof("consumer_secret\"\r\n\r\n")-1;
+    actualsize +=sizeof("consumer_secret\"\r\n\r\n")-1;
+    strcpy(positionPointer, m_consumer_secret);
+    positionPointer += strlen(m_consumer_secret);
+    actualsize += strlen(m_consumer_secret);
+    strcpy(positionPointer, "\r\n");
+    positionPointer+=2;
+    actualsize +=2;
+
+    //OAuth Token
+    strcpy(positionPointer, HEADER);
+    positionPointer += sizeof(HEADER)-1;
+    actualsize += sizeof(HEADER) -1;
+    strcpy(positionPointer, "\r\n");
+    positionPointer += 2;
+    actualsize += 2;
+
+    strcpy(positionPointer, headerline);
+    positionPointer += strlen(headerline);
+    actualsize += strlen(headerline);
+    strcpy(positionPointer, "oauth_token\"\r\n\r\n");
+    positionPointer += sizeof("oauth_token\"\r\n\r\n")-1;
+    actualsize += sizeof("oauth_token\"\r\n\r\n")-1;
+    strcpy(positionPointer, m_access_token);
+    positionPointer += strlen(m_access_token);
+    actualsize += strlen(m_access_token);
+    strcpy(positionPointer, "\r\n");
+    positionPointer+=2;
+    actualsize += 2;
+
+    //OAuth Secret
+    strcpy(positionPointer, HEADER);
+    positionPointer += sizeof(HEADER)-1;
+    actualsize += sizeof(HEADER) -1;
+    strcpy(positionPointer, "\r\n");
+    positionPointer += 2;
+    actualsize += 2;
+
+    strcpy(positionPointer, headerline);
+    positionPointer += strlen(headerline);
+    actualsize += strlen(headerline);
+    strcpy(positionPointer, "oauth_secret\"\r\n\r\n");
+    positionPointer += sizeof("oauth_secret\"\r\n\r\n")-1;
+    actualsize += sizeof("oauth_secret\"\r\n\r\n")-1;
+    strcpy(positionPointer, m_access_token_secret);
+    positionPointer += strlen(m_access_token_secret);
+    actualsize += strlen(m_access_token_secret);
+    strcpy(positionPointer, "\r\n");
+    positionPointer+=2;
+    actualsize +=2;
+
+    //Twitter Message
+    strcpy(positionPointer, HEADER);
+    positionPointer += sizeof(HEADER)-1;
+    actualsize += sizeof(HEADER) -1;
+    strcpy(positionPointer, "\r\n");
+    positionPointer += 2;
+    actualsize += 2;
+
+    strcpy(positionPointer, headerline);
+    positionPointer += strlen(headerline);
+    actualsize += strlen(headerline);
+    strcpy(positionPointer, "message\"\r\n\r\n");
+    positionPointer += sizeof("message\"\r\n\r\n")-1;
+    actualsize += sizeof("message\"\r\n\r\n")-1;
+    strcpy(positionPointer, twitterMessage);
+    positionPointer += strlen(twitterMessage);
+    actualsize += strlen(twitterMessage);
+    strcpy(positionPointer, "\r\n");
+    positionPointer+=2;
+    actualsize += 2;
+
+    strcpy(positionPointer,HEADER);
+    positionPointer += sizeof(HEADER)-1;
+    actualsize += sizeof(HEADER)-1;
+    strcpy(positionPointer,"\r\nContent-Disposition: form-data; name=\"media\"; filename=\"image.jpg\"\r\n");
+    positionPointer += sizeof("\r\nContent-Disposition: form-data; name=\"media\"; filename=\"image.jpg\"\r\n")-1;
+    actualsize += sizeof("\r\nContent-Disposition: form-data; name=\"media\"; filename=\"image.jpg\"\r\n")-1;
+    strcpy(positionPointer,"Content-Type: image/jpeg\r\n");
+    positionPointer += sizeof("Content-Type: image/jpeg\r\n")-1;
+    actualsize += sizeof("Content-Type: image/jpeg\r\n")-1;
+    strcpy(positionPointer,"Content-Transfer-Encoding: binary\r\n\r\n");
+    positionPointer += sizeof("Content-Transfer-Encoding: binary\r\n\r\n")-1;
+    actualsize+= sizeof("Content-Transfer-Encoding: binary\r\n\r\n")-1;
+
+    if (actualsize != neededSize) printf("ERROR in parameters: Calculated size: %i. Actual size: %i.\n", neededSize,actualsize);
+    writing_position += actualsize;
+    if (DEBUG) printf("Wrote parameters to buffer.\n");
+    sentParameters = true;
+
+}
+void TwitPic::sendImageData() {
+    int availableSize;
+    int amountRead=0;
+    char* positionPointer;
+
+    if (TRACE) printf("-----------------------TRACE: sendImageData\n");
+    
+    if (writing_position > 0) return;
+    //fseek(imgFile,-2000,SEEK_END);
+    positionPointer = sendBuf;
+    positionPointer += writing_position;
+    availableSize = SENDING_BUFFER_SIZE - writing_position;
+    amountRead = fread(positionPointer, 1, availableSize, imgFile);
+    writing_position += amountRead;
+    if (DEBUG) printf("Wrote %i bytes of image to buffer.\n",amountRead);
+    if (feof(imgFile)) {
+        if (DEBUG) printf("Finished writing file to buffer.\n");
+        sentImageData = true;
+    }
+}
+void TwitPic::sendFooter() {
+    int availableSize;
+    int neededSize;
+    char* positionPointer;
+    
+    if (TRACE) printf("-----------------------TRACE: sendFooter\n");
+    
+    availableSize = SENDING_BUFFER_SIZE - writing_position;
+    neededSize = sizeof("\r\n")-1 +
+                 sizeof(FOOTER) - 1 +
+                 sizeof("\r\n") - 1;
+    if (availableSize < neededSize) return;
+
+    positionPointer = sendBuf;
+    positionPointer += writing_position;
+    strcpy(positionPointer,"\r\n");
+    positionPointer+=2;
+    strcpy(positionPointer, FOOTER);
+    positionPointer+=sizeof(FOOTER)-1;
+    strcpy(positionPointer,"\r\n");
+    positionPointer+=2;
+
+    writing_position+=neededSize;
+    if (DEBUG) printf("Wrote footer to buffer.\n");
+    sentFooter=true;
+}
+void TwitPic::sendNextChunk() {
+    int amountToSend;
+    int amountSent;
+    char* bufPointer;
+    if (TRACE) printf("-----------------------TRACE: sendNextChunk\n");
+    //TODO: try both ways of doint this: looped and not.
+    do {
+        if (writing_position == 0) {
+            if (!sentHeaders) {
+                sendHeaders();
+            } else if (!sentParameters) {
+                sendParameters();
+            } else if (!sentImageData) {
+                sendImageData();
+            } else if (!sentFooter) {
+                sendFooter();
+            }
+        }
+        amountToSend = MIN(writing_position,SENDING_CHUNK_SIZE);
+        if (sentFooter && amountToSend == 0) {
+            finishedSending = true;
+            //getResponse();
+        }
+
+        amountSent = socket.send(sendBuf, amountToSend);
+        totalSentData += amountSent;
+
+        if (DEBUG) printf("---Total sent data: %i bytes\n",totalSentData);
+
+        bufPointer = sendBuf + amountSent;
+        memmove((void*)sendBuf, (void*)bufPointer, writing_position - amountSent);
+        writing_position -= amountSent;
+    } while (!finishedSending && amountSent == amountToSend); //if sent less than intended, stop sending until WRITEABLE.
+}
+void TwitPic::getResponse() {
+    int amountReceived;
+    char* okSpot;
+
+    if (TRACE) printf("-----------------------TRACE: getResponse\n");
+    if (DEBUG) printf("Checking for response\n");
+    amountReceived = socket.recv(recvBuf, RECEIVING_BUFFER_SIZE-1);
+    recvBuf[amountReceived]='\0';
+    if (amountReceived > 0 && DEBUG) printf("Received response: %s\n",recvBuf);
+
+    okSpot = strstr(recvBuf,"200 OK");
+    if (okSpot != NULL) {
+        positiveResponse = true;
+        readyToReturn = true;
+    } else if (finishedSending && amountReceived > 0) {
+        positiveResponse = false;
+        readyToReturn = true;
+    }
+}
+
+void TwitPic::flushResponse() {
+//no longer needed
+}
diff -r 000000000000 -r e8e33b39c3cc TwitPic.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TwitPic.h	Sat Feb 26 20:07:01 2011 +0000
@@ -0,0 +1,52 @@
+/*
+  TwitPic.h - TwitPic Image Uploader for mbed
+  Copyright (c) novachild 2011. All rights reserved.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  
+  REQUIRES: EthernetNetIf, DNSResolver, some sort of file access (SD, local, etc)
+
+*/
+
+#ifndef TwitPic_h
+#define TwitPic_h
+
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "TCPSocket.h"
+#include "host.h"
+#include "ipaddr.h"
+#include "dnsresolve.h"
+
+class TwitPic {
+public:
+    TwitPic(const char *twitpic_api_key, const char *consumer_key, const char *consumer_secret, const char *access_token, const char *access_token_secret);
+    int upload(const char *message,
+               FILE *img,
+               bool toPost = false);
+
+    int uploadAndPost(const char *message,
+                      FILE *imgFile);
+
+private:
+    Host server;
+    TCPSocket socket;
+    
+    
+    void handleTCPSocketEvents(TCPSocketEvent ev);
+
+    void sendHeaders();
+    void sendParameters();
+    void sendImageData();
+    void sendFooter();
+    void sendNextChunk();
+    
+    void getResponse();
+    void flushResponse();
+
+};
+
+
+#endif