00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
00143
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
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
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
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
00439
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
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
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
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
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
00499
00500
00501
00502
00503
00504
00505 tmp = strstr(line + strlen(http->boundary), http->boundary);
00506
00507 do{
00508
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
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
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
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
00592 if(tmp) free(tmp);
00593 } else if(!strcmp(token, "HEAD")) {
00594
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
00629 http->http_performative = HTTP_RESPONSE;
00630
00631 free(token);
00632 cur = http_GetToken(cur, &token);
00633 sscanf(token, "%d", &http->response_code);
00634
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
00645
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
00670 if (string[0] == '\r' && string[1] == '\n') {
00671 *token = NULL;
00672 return NULL;
00673 }
00674
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
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
00777
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
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
00799
00800
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
00811 dynstring_Append(http_body, boundary);
00812 dynstring_Append(http_body, "--");
00813 dynstring_Append(http_body, "\r\n\r\n");
00814
00815
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);
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