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

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 205 $ : Last Committed Revision
00003  * $Date: 2008年07月11日 17:08:41 -0700 (2008年7月11日) $ : 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 Tue Oct 28 17:03:22 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /