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

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

Generated on Mon Jun 23 16:01:10 2008 for Mobile-C by  doxygen 1.5.4