/home/dko/projects/mobilec/trunk/src/mtp_http.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 174 $ : Last Committed Revision
00003  * $Date: 2008-06-24 10:50:29 -0700 (Tue, 24 Jun 2008) $ : Last Committed Date */
00004 /*[
00005  * Copyright (c) 2007 Integration Engineering Laboratory
00006                       University of California, Davis
00007  *
00008  * Permission to use, copy, and distribute this software and its
00009  * documentation for any purpose with or without fee is hereby granted,
00010  * provided that the above copyright notice appear in all copies and
00011  * that both that copyright notice and this permission notice appear
00012  * in supporting documentation.
00013  *
00014  * Permission to modify the software is granted, but not the right to
00015  * distribute the complete modified source code.  Modifications are to
00016  * be distributed as patches to the released version.  Permission to
00017  * distribute binaries produced by compiling modified sources is granted,
00018  * provided you
00019  *   1. distribute the corresponding source modifications from the
00020  *    released version in the form of a patch file along with the binaries,
00021  *   2. add special version identification to distinguish your version
00022  *    in addition to the base release version number,
00023  *   3. provide your name and address as the primary contact for the
00024  *    support of your modified version, and
00025  *   4. retain our contact information in regard to use of the base
00026  *    software.
00027  * Permission to distribute the released version of the source code along
00028  * with corresponding source modifications in the form of a patch file is
00029  * granted with same provisions 2 through 4 for binary distributions.
00030  *
00031  * This software is provided "as is" without express or implied warranty
00032  * to the extent permitted by applicable law.
00033 ]*/
00034 
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <time.h>
00039 #ifndef _WIN32
00040 #include <unistd.h>
00041 #include "config.h"
00042 #else
00043 #include "winconfig.h"
00044 #endif
00045 #include "include/connection.h"
00046 #include "include/mtp_http.h"
00047 #include "include/macros.h"
00048 #include "include/mc_error.h"
00049 #include "include/message.h"
00050 #include "include/dynstring.h"
00051 
00052 int
00053 mtp_http_Destroy(mtp_http_p http)
00054 {
00055   int i;
00056 #define SAFE_FREE(elem) \
00057   if(elem) \
00058     free(elem)
00059 
00060   SAFE_FREE(http->http_version);
00061   SAFE_FREE(http->host);
00062   SAFE_FREE(http->return_code);
00063   SAFE_FREE(http->target);
00064   SAFE_FREE(http->date);
00065   SAFE_FREE(http->server);
00066   SAFE_FREE(http->accept_ranges);
00067   SAFE_FREE(http->content_length);
00068   SAFE_FREE(http->connection);
00069   SAFE_FREE(http->content_type);
00070   SAFE_FREE(http->user_agent);
00071   if(http->content != NULL) {
00072     for(i = 0; i < http->message_parts; i++) {
00073       SAFE_FREE(http->content[i].content_type);
00074       SAFE_FREE(http->content[i].data);
00075     }
00076   }
00077   SAFE_FREE(http->content);
00078   SAFE_FREE(http->boundary);
00079   SAFE_FREE(http);
00080 #undef SAFE_FREE
00081   return 0;
00082 }
00083 
00084   mtp_http_p
00085 mtp_http_New(void)
00086 {
00087   mtp_http_p http;
00088   http = (mtp_http_p)malloc(sizeof(mtp_http_t));
00089   CHECK_NULL(http, exit(0););
00090   memset(http, 0, sizeof(mtp_http_t));
00091   http->content = NULL;
00092   return http;
00093 }
00094 
00095 int
00096 mtp_http_InitializeFromConnection
00097 (
00098  mtp_http_p http,
00099  connection_p connection
00100  )
00101 {
00102   int i=1;
00103   int n;
00104   char *message_string;
00105   char *buffer;
00106   int message_size = 0;
00107 
00108   buffer = (char*) malloc(sizeof(char) * (SOCKET_INPUT_SIZE + 1));
00109   CHECK_NULL(buffer, exit(0););
00110   message_string = (char*) malloc(sizeof(char) * (SOCKET_INPUT_SIZE + 1));
00111   CHECK_NULL(message_string, exit(0););
00112   message_string[0] = '\0';
00113   buffer[0] = '\0';
00114 
00115   while(1){
00116 #ifndef _WIN32
00117     n = recvfrom(connection->clientfd,
00118         (void *) buffer,
00119         (size_t) sizeof(char)*SOCKET_INPUT_SIZE,
00120         0,
00121         (struct sockaddr *) 0,
00122         (socklen_t *) 0);
00123 #else
00124     n = recvfrom(connection->clientfd,
00125         (void *) buffer,
00126         (size_t) sizeof(char)*SOCKET_INPUT_SIZE,
00127         0,
00128         (struct sockaddr *) 0,
00129         0);
00130 #endif
00131     if (n < 0) {
00132       free(buffer);
00133       return MC_ERR_CONNECT;
00134     } 
00135     else if (n == 0 || n < SOCKET_INPUT_SIZE) {
00136       if (n != 0) {
00137         buffer[n] = '\0';
00138         strcat(message_string, buffer);
00139       }
00140       free(buffer);
00141       if(mtp_http_Parse(http, message_string)) {
00142         /* Reply with an HTTP error code */
00143         buffer = malloc
00144           (
00145            sizeof(char) * 
00146            (
00147             strlen
00148             (
00149              "HTTP/1.0 503 Service Unavailable\r\nConnection: Close\r\n\r\nMobile C"
00150             )+1
00151            )
00152           );
00153         strcpy
00154           (
00155            buffer,
00156            "HTTP/1.0 503 Service Unavailable\r\nConnection: Close\r\n\r\nMobile C"
00157           );
00158         send
00159           (
00160            connection->clientfd,
00161            (void*)buffer,
00162            sizeof(char)*(strlen(buffer)),
00163            0
00164           );
00165         free(message_string);
00166         free(buffer);
00167         return ERR;
00168       } else {
00169         free(message_string);
00170       }
00171 
00172       if (n < SOCKET_INPUT_SIZE) {
00173         buffer = strdup("HTTP/1.0 200 OK\r\nConnection: Close\r\n\r\nMobile C");
00174         send(
00175             connection->clientfd,
00176             (void*)buffer,
00177             sizeof(char)*strlen(buffer),
00178             0 );
00179 #ifdef _WIN32
00180         closesocket(connection->clientfd);
00181 #else
00182         close(connection->clientfd);
00183 #endif
00184         free(buffer);
00185       }
00186       break;
00187     } else {
00188       message_size += n;
00189       buffer[n] = '\0';
00190       i++;
00191       strcat(message_string, buffer);
00192       message_string = realloc
00193         (
00194          message_string, 
00195          sizeof(char) * (SOCKET_INPUT_SIZE+1) * i
00196         );
00197       CHECK_NULL(message_string, exit(0););
00198       buffer[0] = '\0';
00199       if (!strcmp
00200           (
00201            message_string + message_size - 4,
00202            "\r\n\r\n"
00203           )
00204          )
00205         break;
00206     }
00207   }
00208   return 0;
00209 }
00210 
00211 const char* http_GetExpression(const char* string, char** expr)
00212 {
00213   int i;
00214   int j;
00215   int success_flag = 0;
00216   const char* next_expr_ptr;
00217   /* Check to see if we are at the end of the HTTP header */
00218   if( 
00219       (string[0] == '\n') ||
00220       (string[0] == '\r' && string[1] == '\n')
00221     ) 
00222   {
00223     for(i = 0; string[i] == '\n' || string[i] == '\r'; i++);
00224     *expr = NULL;
00225     return string+i;
00226   }
00227   /* FIXME */
00228   for(i = 0;string[i] != '\0';i++) {
00229     if (
00230         (
00231          (string[i] == '\r') &&
00232          (string[i+1] == '\n') &&
00233          (string[i+2] != '\t') &&
00234          (string[i+2] != ' ')
00235         ) 
00236         ||
00237         (
00238          string[i] == '\n' && 
00239          string[i+1] != '\t' &&
00240          string[i+2] != ' '
00241         )
00242        )
00243     {
00244       success_flag = 1;
00245       break;
00246     } 
00247   }
00248   if(success_flag)
00249   {
00250     *expr = (char*)malloc
00251       (
00252        sizeof(char) * (i+1)
00253       );
00254     for(j = 0; j < i; j++) {
00255       (*expr)[j] = string[j];
00256     }
00257     (*expr)[j] = '\0';
00258     next_expr_ptr = &(string[i]);
00259     if(next_expr_ptr[0] == '\r' && next_expr_ptr[1] == '\n') {
00260       next_expr_ptr += 2;
00261     } else if (next_expr_ptr[0] == '\n') {
00262       next_expr_ptr++;
00263     }
00264     return next_expr_ptr;
00265   } else {
00266     return NULL;
00267   }
00268 }
00269       
00270 int http_ParseExpression(
00271     const char* expression_string,
00272     char** name,
00273     char** value
00274     )
00275 {
00276   int i=0;
00277   const char* tmp;
00278   const char* charptr;
00279   if(expression_string == NULL) {
00280     *name = NULL;
00281     *value = NULL;
00282     return MC_ERR_PARSE;
00283   }
00284   tmp = expression_string;
00285   if (tmp == NULL || (!strncmp(tmp, "\r\n", 2)) || (!strncmp(tmp, "\n", 1))) {
00286     *name = NULL;
00287     *value = NULL;
00288     return MC_ERR_PARSE;
00289   }
00290   for(; *tmp!=':' && *tmp!='\0'; tmp++)
00291     i++;
00292   if(*tmp == '\0') {
00293     *name = NULL;
00294     *value = NULL;
00295     return MC_ERR_PARSE;
00296   }
00297   *name = (char*)malloc
00298     (
00299      sizeof(char) * (i+1)
00300     );
00301   CHECK_NULL(*name, exit(0););
00302   charptr = expression_string;
00303   i=0;
00304   while(charptr != tmp) {
00305     (*name)[i] = *charptr;
00306     i++;
00307     charptr++;
00308   }
00309   (*name)[i] = '\0';
00310 
00311   tmp++;
00312   while
00313     (
00314      (*tmp == ' ') ||
00315      (*tmp == '\t')
00316     )
00317       tmp++;
00318 
00319   *value = (char*)malloc
00320     (
00321      sizeof(char) * 
00322      (strlen(tmp) + 1)
00323     );
00324   CHECK_NULL(*value, exit(0););
00325   strcpy(*value, tmp);
00326   return MC_SUCCESS;
00327 }
00328 
00329 int
00330 mtp_http_Parse(struct mtp_http_s* http, const char* string)
00331 {
00332   const char* line = NULL;
00333   char* expr = NULL;
00334   char* name = NULL;
00335   char* value = NULL;
00336   char* tmp;
00337   char* tmp2;
00338   int i;
00339 
00340   int err_code = 0;
00341 
00342   line = string;
00343   line = http_ParseHeader
00344     (
00345      http,
00346      line
00347     );
00348   do
00349   {
00350     line = http_GetExpression
00351       (
00352        line,
00353        &expr
00354       );
00355 
00356     err_code = http_ParseExpression
00357       (
00358        expr,
00359        &name,
00360        &value
00361       );
00362     if
00363       (
00364        (name == NULL) ||
00365        (value == NULL)
00366       )
00367       {
00368         if (expr != NULL) {
00369           free(expr);
00370         }
00371         break;
00372       }
00373 #define HTTP_PARSE_EXPR( parse_name, struct_name ) \
00374     if ( !strcmp(name, parse_name) ) { \
00375       http->struct_name = (char*)malloc \
00376       ( \
00377         sizeof(char) * \
00378         (strlen(value)+1) \
00379       ); \
00380       strcpy(http->struct_name, value); \
00381     } else
00382 
00383     HTTP_PARSE_EXPR( "Host", host )
00384     HTTP_PARSE_EXPR( "Date", date )
00385     HTTP_PARSE_EXPR( "Server", server )
00386     HTTP_PARSE_EXPR( "Accept-Ranges", accept_ranges )
00387     HTTP_PARSE_EXPR( "Content-Length", content_length)
00388     HTTP_PARSE_EXPR( "Connection", connection )
00389     HTTP_PARSE_EXPR( "Content-Type", content_type)
00390     HTTP_PARSE_EXPR( "User-Agent", user_agent)
00391     HTTP_PARSE_EXPR( "Cache-Control", cache_control)
00392     HTTP_PARSE_EXPR( "MIME-Version", mime_version)
00393     HTTP_PARSE_EXPR( "Mime-Version", mime_version)
00394     {
00395       fprintf(stderr, "Warning: Unknown http name: %s. %s:%d\n",
00396           name, __FILE__, __LINE__);
00397     }
00398 #undef HTTP_PARSE_EXPR
00399 
00400 #define SAFE_FREE( object ) \
00401     if(object) free(object); \
00402     object = NULL
00403 
00404     SAFE_FREE(expr);
00405     SAFE_FREE(name);
00406     SAFE_FREE(value);
00407 #undef SAFE_FREE
00408      
00409   } while(line != NULL && err_code == MC_SUCCESS);
00410   /* If the content type is multipart/mixed, then we need to
00411    * figure out how many parts there are. */
00412   if( 
00413       http->content_type != NULL &&
00414       !strncmp(
00415         http->content_type,
00416         "multipart/mixed",
00417         strlen("multipart/mixed")
00418         ) 
00419     ) 
00420   {
00421     tmp = strstr(http->content_type, "boundary=");
00422     tmp += strlen("boundary=.");
00423     tmp2 = strchr(tmp, '\"');
00424     http->boundary = (char*)malloc(sizeof(char) * (tmp2 - tmp + 3));
00425     /* We must remember to include the leading '--' for the boundary */
00426     http->boundary[0] = '-';
00427     http->boundary[1] = '-';
00428     for (i = 0; tmp != tmp2; i++, tmp++) {
00429       http->boundary[i+2] = *tmp;
00430     }
00431     http->boundary[i+2] = '\0';
00432 
00433     /* Count the number of message parts in the message */
00434     tmp = (char*)line;
00435     http->message_parts = 0;
00436     while((tmp = strstr(tmp, http->boundary))) {
00437       http->message_parts++;
00438       tmp++;
00439     }
00440     http->message_parts--;
00441   } else {
00442     http->boundary = NULL;
00443     http->message_parts = 1;
00444   }
00445 
00446   if (http->message_parts == 1) { 
00447     http->content = (struct mtp_http_content_s*)malloc(sizeof(struct mtp_http_content_s));
00448     /* Copy rest of contents into the data member */
00449     if (line != NULL) {
00450       http->content->data = (void*)malloc
00451         (
00452          sizeof(char) * 
00453          (strlen(line)+1)
00454         );
00455       strcpy((char*)http->content->data, line);
00456       if (http->content_type != NULL) {
00457         http->content->content_type = strdup(http->content_type);
00458       }
00459     }
00460   } else {
00461     http->content = (struct mtp_http_content_s*)malloc(
00462         sizeof(struct mtp_http_content_s) * http->message_parts );
00463     memset(http->content, 0, sizeof(struct mtp_http_content_s) * http->message_parts);
00464     /* Find the boundary */
00465     line = strstr(line, http->boundary);
00466     line += strlen(http->boundary);
00467     line = strchr(line, '\n');
00468     line++;
00469     for(i = 0; i < http->message_parts; i++) {
00470       /* For each part, we must:
00471        * 1. Find the boundary
00472        * 2. Parse the attributes, until we
00473        * 3. Find the empty line
00474        * 4. Copy the data up to the next boundary */
00475       
00476       /* Find the end boundary */
00477       tmp = strstr(line + strlen(http->boundary), http->boundary);
00478       /* Parse the attributes */
00479       do{
00480         /* FIXME */
00481 
00482         line = http_GetExpression
00483           (
00484            line,
00485            &expr
00486           );
00487 
00488         err_code = http_ParseExpression
00489           (
00490            expr,
00491            &name,
00492            &value
00493           );
00494         if
00495           (
00496            (name == NULL) ||
00497            (value == NULL)
00498           )
00499           {
00500             if (expr != NULL) {
00501               free(expr);
00502             }
00503             break;
00504           }
00505         if (!strcmp(name, "Content-Type")) {
00506           http->content[i].content_type = (char*)malloc(
00507               sizeof(char) * (strlen(value)+1));
00508           strcpy(http->content[i].content_type, value);
00509         }
00510 
00511         /* Clean up memory */
00512         if (expr != NULL) {
00513           free(expr);
00514           expr = NULL;
00515         }
00516         if (name != NULL) {
00517           free(name);
00518           name = NULL;
00519         }
00520         if (value != NULL) {
00521           free(value);
00522           value = NULL;
00523         }
00524       } while(line != NULL && err_code == MC_SUCCESS);
00525       /* Copy the data */
00526       http->content[i].data = (void*)malloc(tmp-line+sizeof(char));
00527       memcpy(http->content[i].data, line, tmp-line);
00528       ((char*)http->content[i].data)[tmp-line] = '\0';
00529       /* Move 'line' to the next boundary */
00530       line = tmp + strlen(http->boundary);
00531       line = strchr(line, '\n');
00532       line++;
00533     }
00534   }
00535   if (
00536       (http->http_performative == HTTP_POST) ||
00537       (http->http_performative == HTTP_PUT) ||
00538       (http->http_performative == HTTP_RESPONSE)
00539      )
00540     return 0;
00541   else
00542     return 1;
00543 }
00544 
00545 const char* http_ParseHeader(
00546     mtp_http_p http,
00547     const char* string )
00548 {
00549   const char* cur;
00550   char* token;
00551   char* tmp = NULL;
00552   char* target;
00553   int len;
00554 
00555   cur = string;
00556   cur = http_GetToken(cur, &token);
00557   if (token == NULL) {
00558     return NULL;
00559   }
00560   if (!strcmp(token, "GET")) {
00561     http->http_performative = HTTP_GET;
00562     cur = http_GetToken(cur, &tmp);
00563     /* We don't support 'get' yet */
00564     if(tmp) free(tmp);
00565   } else if(!strcmp(token, "HEAD")) {
00566     /* Don't support this yet */
00567     http->http_performative = HTTP_HEAD;
00568   } else if(!strcmp(token, "POST")) {
00569     http->http_performative = HTTP_POST;
00570     cur = http_GetToken(cur, &tmp);
00571     if(tmp != NULL) {
00572       if(!strncmp(tmp, "http://",7)) {
00573         target = strchr(tmp+7, (int)'/');
00574       } else {
00575         target = strchr(tmp, (int)'/');
00576       }
00577       if (target == NULL)
00578         target = tmp;
00579       http->target = (char*) malloc(sizeof(char) * (strlen(target)+1));
00580       strcpy(http->target, target);
00581       free(tmp);
00582     }
00583   } else if(!strcmp(token, "PUT")) {
00584     http->http_performative = HTTP_PUT;
00585     cur = http_GetToken(cur, &tmp);
00586     if (tmp != NULL) {
00587       http->target = (char*)malloc(sizeof(char)*(strlen(tmp)+1));
00588       strcpy(http->target, tmp);
00589       free(tmp);
00590     }
00591   } else if(!strcmp(token, "DELETE")) {
00592     http->http_performative = HTTP_DELETE;
00593   } else if(!strcmp(token, "TRACE")) {
00594     http->http_performative = HTTP_TRACE;
00595   } else if(!strcmp(token, "OPTIONS")) {
00596     http->http_performative = HTTP_OPTIONS;
00597   } else if(!strcmp(token, "CONNECT")) {
00598     http->http_performative = HTTP_CONNECT;
00599   } else if(!strncmp(token, "HTTP/", 5)) {
00600     /* This is a response message */
00601     http->http_performative = HTTP_RESPONSE;
00602     /* We expect a status code */
00603     free(token);
00604     cur = http_GetToken(cur, &token);
00605     sscanf(token, "%d", &http->response_code);
00606     /* And now a status string */
00607     len = strstr(cur, "\r\n") - 1;
00608     http->response_string = malloc(
00609         sizeof(char) * (len +1) );
00610     strncpy(
00611         http->response_string,
00612         cur,
00613         len );
00614     http->response_string[len] = '\0';
00615   } else {
00616     /* FIXME */
00617     /* Illegal performative */
00618     http->http_performative = HTTP_PERFORMATIVE_UNDEF;
00619   }
00620   free(token);
00621   cur = string;
00622   while(*cur != '\0') {
00623     if(*cur == '\n') {
00624       while (*cur == '\n' || *cur == '\r' || *cur == ' ')
00625         cur++;
00626       break;
00627     }
00628     cur++;
00629   }
00630   return cur;
00631 }
00632 
00633 const char*
00634 http_GetToken(const char* string, char** token)
00635 {
00636   const char* cur;
00637   const char* begin;
00638   char* itr;
00639   
00640   cur = string;
00641   /* See if it's an empty line */
00642   if (string[0] == '\r' && string[1] == '\n') {
00643     *token = NULL;
00644     return NULL;
00645   }
00646   /* Get rid of initial whitespace */
00647   while(*cur == ' ' || *cur == '\t' || *cur == '\r' || *cur == '\n') cur++;
00648 
00649   begin = cur;
00650   while(*cur != '\0') {
00651     cur++;
00652     if (*cur == ' ' || *cur == '\t' || *cur == '\r' || *cur == '\n')
00653       break;
00654   }
00655   cur--;
00656   *token = (char*)malloc(cur - begin + 4*sizeof(char));
00657   itr = *token;
00658   while (begin <= cur) {
00659     *itr = *begin;
00660     itr++;
00661     begin++;
00662   }
00663   *itr='\0';
00664   return cur+1;
00665 }
00666 
00667 int mtp_http_ParseResponse(struct mtp_http_s* http, const char* string)
00668 {
00669 
00670 }
00671 
00672 int 
00673 mtp_http_ComposeMessage(message_p message)
00674 {
00675   char* http_header;
00676   char* tmp;
00677   char buf[20];
00678   if (message->isHTTP) {
00679     /* message reports that it already is an http message. No need to continue. */
00680     return 0;
00681   }
00682 
00683   http_header = (char*)malloc
00684     (
00685      sizeof(char) * (1400 + strlen(message->to_address))
00686     );
00687   http_header[0] = '\0';
00688   strcat(http_header, "POST /");
00689   strcat(http_header, message->target);
00690   strcat(http_header, " HTTP/1.0\r\n");
00691   strcat(http_header, "User-Agent: MobileC/");
00692   strcat(http_header, PACKAGE_VERSION);
00693   strcat(http_header, "\r\n");
00694   strcat(http_header, "Host: ");
00695   strcat(http_header, message->to_address);
00696   strcat(http_header, "\r\n");
00697   strcat(http_header, "Content-Type: text/plain\r\n");
00698   strcat(http_header, "Connection: Close\r\n");
00699   strcat(http_header, "Content-Length: ");
00700   sprintf(buf, "%d", strlen(message->message_body) + 1);
00701   strcat(http_header, buf);
00702   strcat(http_header, "\r\n\r\n");
00703 
00704   tmp = (char*)malloc
00705     (
00706      sizeof(char) * 
00707      (strlen(http_header) + strlen(message->message_body) + 1)
00708     );
00709   tmp[0] = '\0';
00710   strcpy(tmp, http_header);
00711   strcat(tmp, message->message_body);
00712   free(message->message_body);
00713   message->message_body = tmp;
00714   free(http_header);
00715   return MC_SUCCESS;
00716 }
00717 
00718 struct message_s* 
00719 mtp_http_CreateMessage(
00720     mtp_http_t* mtp_http,
00721     char* hostname,
00722     int port)
00723 {
00724   int i;
00725   int num;
00726   char buf[30];
00727   char boundary[30];
00728   message_t* message;
00729   dynstring_t* http_header;
00730   dynstring_t* http_body;
00731   http_header = dynstring_New();
00732   http_body = dynstring_New();
00733   dynstring_Append(http_header, "POST /");
00734   dynstring_Append(http_header, mtp_http->target);
00735   dynstring_Append(http_header, " HTTP/1.1\r\n");
00736   dynstring_Append(http_header, "User-Agent: MobileC/");
00737   dynstring_Append(http_header, PACKAGE_VERSION);
00738   dynstring_Append(http_header, "\r\n");
00739   dynstring_Append(http_header, "Host: ");
00740   dynstring_Append(http_header, mtp_http->host);
00741   dynstring_Append(http_header, ":");
00742   sprintf(buf, "%d", port);
00743   dynstring_Append(http_header, buf);
00744   dynstring_Append(http_header, "\r\n");
00745   dynstring_Append(http_header, "Cache-Control: no-cache\r\n");
00746   dynstring_Append(http_header, "Mime-Version: 1.0\r\n");
00747 
00748   /* The next part of the message will be different depending on 
00749    * how many message parts we have.  */
00750   if(mtp_http->message_parts == 1) {
00751     dynstring_Append(http_header, "Content-Type: text/plain\r\n");
00752     dynstring_Append(http_header, "Content-Length: ");
00753     sprintf(buf, "%d", strlen((char*)mtp_http->content[0].data));
00754     dynstring_Append(http_header, buf);
00755     dynstring_Append(http_header, "\r\n\r\n");
00756     dynstring_Append(http_header, (char*)mtp_http->content[0].data);
00757   } else {
00758     /* We need to generate a random boundary. */
00759     srand(time(NULL));
00760     strcpy(boundary, "--");
00761     for(i = 2; i < 26; i++) {
00762       num = rand() % 36;
00763       if(num < 10) {
00764         boundary[i] = (char)(48 + num);
00765       } else {
00766         boundary[i] = (char)( (num-10)+65);
00767       }
00768     }
00769     boundary[i] = '\0';
00770     /* FIXME: A randomly generated boundary should now be stored in boundary. Should
00771      * we check to see if there is a match within the body? The chances of collision are
00772      * infinitessimal. */
00773     dynstring_Append(http_body, "This is not part of the MIME multipart encoded message.\r\n");
00774     for(i = 0; i<mtp_http->message_parts; i++) {
00775       dynstring_Append(http_body, boundary);
00776       dynstring_Append(http_body, "\r\nContent-Type: ");
00777       dynstring_Append(http_body, mtp_http->content[i].content_type);
00778       dynstring_Append(http_body, "\r\n\r\n");
00779       dynstring_Append(http_body, (char*)mtp_http->content[i].data);
00780       dynstring_Append(http_body, "\r\n");
00781     }
00782     /* Append one last boundary */
00783     dynstring_Append(http_body, boundary);
00784     dynstring_Append(http_body, "--");
00785     dynstring_Append(http_body, "\r\n\r\n");
00786 
00787     /* Set the content length in the header */
00788     dynstring_Append(http_header, "Content-Length: ");
00789     sprintf(buf, "%d", http_body->len-2 );
00790     dynstring_Append(http_header, buf);
00791     dynstring_Append(http_header, "\r\n");
00792     dynstring_Append(http_header, "Content-Type: multipart/mixed ; boundary=\"");
00793     dynstring_Append(http_header, boundary+2); /* Omit leading "--" */
00794     dynstring_Append(http_header, "\"\r\n");
00795 
00796   }
00797   dynstring_Append(http_header, "Connection: Close\r\n\r\n");
00798   message = message_New();
00799   message->to_address = (char*)malloc(
00800       sizeof(char) * (strlen(hostname)+15) );
00801   sprintf(message->to_address, "%s:%d", hostname, port);
00802   message->message_body = (char*) malloc( 
00803       sizeof(char) * (http_header->len + http_body->len + 1));
00804   strcpy(message->message_body, http_header->message);
00805   strcat(message->message_body, http_body->message);
00806   dynstring_Destroy(http_header);
00807   dynstring_Destroy(http_body);
00808   message->isHTTP = 1;
00809   return message;
00810 }
00811 

Generated on Tue Jul 1 15:29:58 2008 for Mobile-C by  doxygen 1.5.4