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 #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
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
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
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
00408
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
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
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
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
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
00468
00469
00470
00471
00472
00473
00474 tmp = strstr(line + strlen(http->boundary), http->boundary);
00475
00476 do{
00477
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
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
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
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
00561 if(tmp) free(tmp);
00562 } else if(!strcmp(token, "HEAD")) {
00563
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
00598 http->http_performative = HTTP_RESPONSE;
00599
00600 free(token);
00601 cur = http_GetToken(cur, &token);
00602 sscanf(token, "%d", &http->response_code);
00603
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
00614
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
00639 if (string[0] == '\r' && string[1] == '\n') {
00640 *token = NULL;
00641 return NULL;
00642 }
00643
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
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
00746
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
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
00768
00769
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
00780 dynstring_Append(http_body, boundary);
00781 dynstring_Append(http_body, "--");
00782 dynstring_Append(http_body, "\r\n\r\n");
00783
00784
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);
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