/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/mtp_http.c

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

Generated on Fri Jul 11 17:59:45 2008 for Mobile-C by  doxygen 1.5.4