LTP GCOV extension - code coverage report
Current view: directory - ext/http - http_request_body_api.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 77
Code covered: 75.3 % Executed lines: 58
Legend: not executed executed

       1                 : /*
       2                 :     +--------------------------------------------------------------------+
       3                 :     | PECL :: http                                                       |
       4                 :     +--------------------------------------------------------------------+
       5                 :     | Redistribution and use in source and binary forms, with or without |
       6                 :     | modification, are permitted provided that the conditions mentioned |
       7                 :     | in the accompanying LICENSE file are met.                          |
       8                 :     +--------------------------------------------------------------------+
       9                 :     | Copyright (c) 2004-2007, Michael Wallner <mike@php.net>            |
      10                 :     +--------------------------------------------------------------------+
      11                 : */
      12                 : 
      13                 : /* $Id: http_request_body_api.c,v 1.17 2007/02/07 11:50:27 mike Exp $ */
      14                 : 
      15                 : #define HTTP_WANT_CURL
      16                 : #include "php_http.h"
      17                 : 
      18                 : #ifdef HTTP_HAVE_CURL
      19                 : 
      20                 : #include "php_http_api.h"
      21                 : #include "php_http_url_api.h"
      22                 : #include "php_http_request_body_api.h"
      23                 : 
      24                 : #if defined(HAVE_CURL_GETFORMDATA) && !defined(HAVE_CURL_FORMGET)
      25                 : struct FormData {
      26                 :         struct FormData *next;
      27                 :         int type;
      28                 :         char *line;
      29                 :         size_t length;
      30                 : };
      31                 : 
      32                 : CURLcode Curl_getFormData(struct FormData **, struct curl_httppost *post, curl_off_t *size);
      33                 : 
      34                 : static char *file_get_contents(char *file, size_t *len TSRMLS_DC)
      35                 : {
      36                 :         php_stream *s = NULL;
      37                 :         char *buf = NULL;
      38                 :         
      39                 :         if ((s = php_stream_open_wrapper_ex(file, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL, HTTP_DEFAULT_STREAM_CONTEXT))) {
      40                 :                 *len = php_stream_copy_to_mem(s, &buf, (size_t) -1, 0);
      41                 :                 php_stream_close(s);
      42                 :         } else {
      43                 :                 *len = 0;
      44                 :         }
      45                 :         return buf;
      46                 : }
      47                 : 
      48                 : static int curl_formget(struct FormData *post, phpstr *str TSRMLS_DC)
      49                 : {
      50                 :         int fgc_error = 0;
      51                 :         char *fdata;
      52                 :         size_t fsize;
      53                 :         struct FormData *next, *pptr = post;
      54                 :         
      55                 :         while (pptr) {
      56                 :                 next = pptr->next;
      57                 :                 
      58                 :                 if (!fgc_error) {
      59                 :                         if (pptr->type) {
      60                 :                                 if ((fdata = file_get_contents(pptr->line, &fsize TSRMLS_CC))) {
      61                 :                                         phpstr_append(str, fdata, fsize);
      62                 :                                         efree(fdata);
      63                 :                                 } else {
      64                 :                                         fgc_error = 1;
      65                 :                                 }
      66                 :                         } else {
      67                 :                                 phpstr_append(str, pptr->line, pptr->length);
      68                 :                         }
      69                 :                 }
      70                 :                 
      71                 :                 curl_free(pptr->line);
      72                 :                 curl_free(pptr);
      73                 :                 pptr = next;
      74                 :         }
      75                 :         
      76                 :         return fgc_error;
      77                 : }
      78                 : #endif
      79                 : 
      80                 : 
      81                 : /* {{{ http_request_body *http_request_body_new() */
      82                 : PHP_HTTP_API http_request_body *_http_request_body_init_ex(http_request_body *body, int type, void *data, size_t size, zend_bool free ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
      83               9 : {
      84               9 :         if (!body) {
      85               6 :                 body = emalloc_rel(sizeof(http_request_body));
      86                 :         }
      87                 :         
      88               9 :         body->type = type;
      89               9 :         body->free = free;
      90               9 :         body->priv = 0;
      91               9 :         body->data = data;
      92               9 :         body->size = size;
      93                 :         
      94               9 :         return body;
      95                 : }
      96                 : /* }}} */
      97                 : 
      98                 : /* {{{ http_request_body *http_request_body_fill(http_request_body *body, HashTable *, HashTable *) */
      99                 : PHP_HTTP_API http_request_body *_http_request_body_fill(http_request_body *body, HashTable *fields, HashTable *files ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
     100               6 : {
     101               6 :         if (files && (zend_hash_num_elements(files) > 0)) {
     102               2 :                 HashKey key = initHashKey(0);
     103                 :                 zval **data;
     104                 :                 HashPosition pos;
     105               2 :                 struct curl_httppost *http_post_data[2] = {NULL, NULL};
     106                 : 
     107                 :                 /* normal data */
     108               2 :                 if (fields) {
     109               3 :                         FOREACH_HASH_KEYVAL(pos, fields, key, data) {
     110               2 :                                 if (key.type == HASH_KEY_IS_STRING) {
     111                 :                                         CURLcode err;
     112               2 :                                         zval *orig = *data;
     113                 :                                         
     114               2 :                                         convert_to_string_ex(data);
     115               2 :                                         err = curl_formadd(&http_post_data[0], &http_post_data[1],
     116                 :                                                 CURLFORM_COPYNAME,                      key.str,
     117                 :                                                 CURLFORM_COPYCONTENTS,          Z_STRVAL_PP(data),
     118                 :                                                 CURLFORM_CONTENTSLENGTH,        (long) Z_STRLEN_PP(data),
     119                 :                                                 CURLFORM_END
     120                 :                                         );
     121                 :                                         
     122               2 :                                         if (orig != *data) {
     123               0 :                                                 zval_ptr_dtor(data);
     124                 :                                         }
     125                 :                                         
     126               2 :                                         if (CURLE_OK != err) {
     127               0 :                                                 http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post fields: %s", curl_easy_strerror(err));
     128               0 :                                                 curl_formfree(http_post_data[0]);
     129               0 :                                                 return NULL;
     130                 :                                         }
     131                 :                                 }
     132                 :                         }
     133                 :                 }
     134                 : 
     135                 :                 /* file data */
     136               4 :                 FOREACH_HASH_VAL(pos, files, data) {
     137                 :                         zval **file, **type, **name;
     138                 :                         
     139               2 :                         if (Z_TYPE_PP(data) != IS_ARRAY) {
     140               0 :                                 http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Unrecognized type of post file array entry");
     141               2 :                         } else if (     SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "name", sizeof("name"), (void *) &name) ||
     142                 :                                                 SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void *) &type) ||
     143                 :                                                 SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "file", sizeof("file"), (void *) &file)) {
     144               0 :                                 http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Post file array entry misses either 'name', 'type' or 'file' entry");
     145                 :                         } else {
     146                 :                                 CURLcode err;
     147                 :                                 const char *path;
     148               2 :                                 zval *ofile = *file, *otype = *type, *oname = *name;
     149                 :                                 
     150               2 :                                 convert_to_string_ex(file);
     151               2 :                                 convert_to_string_ex(type);
     152               2 :                                 convert_to_string_ex(name);
     153                 :                                 
     154               2 :                                 HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_PP(file), curl_formfree(http_post_data[0]); return NULL);
     155                 :                                 
     156                 :                                 /* this is blatant but should be sufficient for most cases */
     157               2 :                                 if (strncasecmp(Z_STRVAL_PP(file), "file://", lenof("file://"))) {
     158               2 :                                         path = Z_STRVAL_PP(file);
     159                 :                                 } else {
     160               0 :                                         path = Z_STRVAL_PP(file) + lenof("file://");
     161                 :                                 }
     162                 :                                 
     163               2 :                                 err = curl_formadd(&http_post_data[0], &http_post_data[1],
     164                 :                                         CURLFORM_COPYNAME,              Z_STRVAL_PP(name),
     165                 :                                         CURLFORM_FILE,                  path,
     166                 :                                         CURLFORM_CONTENTTYPE,   Z_STRVAL_PP(type),
     167                 :                                         CURLFORM_END
     168                 :                                 );
     169                 :                                 
     170               2 :                                 if (ofile != *file) zval_ptr_dtor(file);
     171               2 :                                 if (otype != *type) zval_ptr_dtor(type);
     172               2 :                                 if (oname != *name) zval_ptr_dtor(name);
     173                 :                                 
     174               2 :                                 if (CURLE_OK != err) {
     175               0 :                                         http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post files: %s", curl_easy_strerror(err));
     176               0 :                                         curl_formfree(http_post_data[0]);
     177               0 :                                         return NULL;
     178                 :                                 }
     179                 :                         }
     180                 :                 }
     181                 :                 
     182               2 :                 return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CURLPOST, http_post_data[0], 0, 1);
     183                 : 
     184               4 :         } else if (fields) {
     185                 :                 char *encoded;
     186                 :                 size_t encoded_len;
     187                 : 
     188               4 :                 if (SUCCESS != http_urlencode_hash_ex(fields, 1, NULL, 0, &encoded, &encoded_len)) {
     189               0 :                         http_error(HE_WARNING, HTTP_E_ENCODING, "Could not encode post data");
     190               0 :                         return NULL;
     191                 :                 }
     192                 :                 
     193               4 :                 return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CSTRING, encoded, encoded_len, 1);
     194                 :         } else {
     195               0 :                 return http_request_body_init_rel(body, HTTP_REQUEST_BODY_CSTRING, estrndup("", 0), 0, 1);
     196                 :         }
     197                 : }
     198                 : 
     199                 : /* STATUS http_request_body_encode(http_request_body *, char**, size_t *) */
     200                 : PHP_HTTP_API STATUS _http_request_body_encode(http_request_body *body, char **buf, size_t *len TSRMLS_DC)
     201               0 : {
     202               0 :         switch (body->type) {
     203                 :                 case HTTP_REQUEST_BODY_CURLPOST:
     204                 :                 {
     205                 : #if defined(HAVE_CURL_FORMGET)
     206                 :                         phpstr str;
     207                 :                         
     208                 :                         phpstr_init_ex(&str, 0x8000, 0);
     209                 :                         if (curl_formget(body->data, &str, (curl_formget_callback) phpstr_append)) {
     210                 :                                 phpstr_dtor(&str);
     211                 :                         } else {
     212                 :                                 phpstr_fix(&str);
     213                 :                                 *buf = PHPSTR_VAL(&str);
     214                 :                                 *len = PHPSTR_LEN(&str);
     215                 :                                 return SUCCESS;
     216                 :                         }
     217                 : #elif defined(HAVE_CURL_GETFORMDATA)
     218                 :                         struct FormData *data;
     219                 :                         curl_off_t size;
     220                 :                         
     221                 :                         if (!Curl_getFormData(&data, body->data, &size)) {
     222                 :                                 phpstr str;
     223                 :                                 
     224                 :                                 phpstr_init_ex(&str, (size_t) size, 0);
     225                 :                                 if (curl_formget(data, &str TSRMLS_CC)) {
     226                 :                                         phpstr_dtor(&str);
     227                 :                                 } else {
     228                 :                                         phpstr_fix(&str);
     229                 :                                         *buf = PHPSTR_VAL(&str);
     230                 :                                         *len = PHPSTR_LEN(&len);
     231                 :                                         return SUCCESS;
     232                 :                                 }
     233                 :                         }
     234                 : #endif
     235               0 :                         break;
     236                 :                 }
     237                 :                 
     238                 :                 case HTTP_REQUEST_BODY_CSTRING:
     239               0 :                         *buf = estrndup(body->data, *len = body->size);
     240               0 :                         return SUCCESS;
     241                 :                 
     242                 :                 default:
     243                 :                         break;
     244                 :         }
     245               0 :         return FAILURE;
     246                 : }
     247                 : /* }}} */
     248                 : 
     249                 : /* {{{ void http_request_body_dtor(http_request_body *) */
     250                 : PHP_HTTP_API void _http_request_body_dtor(http_request_body *body TSRMLS_DC)
     251             182 : {
     252             182 :         if (body) {
     253              10 :                 if (body->free) {
     254               8 :                         switch (body->type) {
     255                 :                                 case HTTP_REQUEST_BODY_CSTRING:
     256               5 :                                         if (body->data) {
     257               5 :                                                 efree(body->data);
     258                 :                                         }
     259               5 :                                         break;
     260                 :         
     261                 :                                 case HTTP_REQUEST_BODY_CURLPOST:
     262               2 :                                         curl_formfree(body->data);
     263               2 :                                         break;
     264                 :         
     265                 :                                 case HTTP_REQUEST_BODY_UPLOADFILE:
     266               1 :                                         php_stream_close(body->data);
     267                 :                                         break;
     268                 :                         }
     269                 :                 }
     270              10 :                 memset(body, 0, sizeof(http_request_body));
     271                 :         }
     272             182 : }
     273                 : /* }}} */
     274                 : 
     275                 : /* {{{ void http_request_body_free(http_request_body *) */
     276                 : PHP_HTTP_API void _http_request_body_free(http_request_body **body TSRMLS_DC)
     277              85 : {
     278              85 :         if (*body) {
     279               6 :                 http_request_body_dtor(*body);
     280               6 :                 efree(*body);
     281               6 :                 *body = NULL;
     282                 :         }
     283              85 : }
     284                 : /* }}} */
     285                 : 
     286                 : #endif /* HTTP_HAVE_CURL */
     287                 : 
     288                 : /*
     289                 :  * Local variables:
     290                 :  * tab-width: 4
     291                 :  * c-basic-offset: 4
     292                 :  * End:
     293                 :  * vim600: noet sw=4 ts=4 fdm=marker
     294                 :  * vim<600: noet sw=4 ts=4
     295                 :  */

Generated by: LTP GCOV extension version 1.5