LTP GCOV extension - code coverage report
Current view: directory - ext/http - http_request_method_api.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 128
Code covered: 78.9 % Executed lines: 101
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_method_api.c,v 1.27 2007/02/07 11:50:27 mike Exp $ */
      14                 : 
      15                 : #define HTTP_WANT_CURL
      16                 : #include "php_http.h"
      17                 : 
      18                 : #include "php_http_api.h"
      19                 : #include "php_http_request_api.h"
      20                 : #include "php_http_request_method_api.h"
      21                 : 
      22                 : #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL) && !defined(WONKY)
      23                 : #       include "php_http_request_object.h"
      24                 : #endif
      25                 : 
      26                 : /* {{{ char *http_request_methods[] */
      27                 : static const char *const http_request_methods[] = {
      28                 :         "UNKNOWN",
      29                 :         /* HTTP/1.1 */
      30                 :         "GET",
      31                 :         "HEAD",
      32                 :         "POST",
      33                 :         "PUT",
      34                 :         "DELETE",
      35                 :         "OPTIONS",
      36                 :         "TRACE",
      37                 :         "CONNECT",
      38                 :         /* WebDAV - RFC 2518 */
      39                 :         "PROPFIND",
      40                 :         "PROPPATCH",
      41                 :         "MKCOL",
      42                 :         "COPY",
      43                 :         "MOVE",
      44                 :         "LOCK",
      45                 :         "UNLOCK",
      46                 :         /* WebDAV Versioning - RFC 3253 */
      47                 :         "VERSION-CONTROL",
      48                 :         "REPORT",
      49                 :         "CHECKOUT",
      50                 :         "CHECKIN",
      51                 :         "UNCHECKOUT",
      52                 :         "MKWORKSPACE",
      53                 :         "UPDATE",
      54                 :         "LABEL",
      55                 :         "MERGE",
      56                 :         "BASELINE-CONTROL",
      57                 :         "MKACTIVITY",
      58                 :         /* WebDAV Access Control - RFC 3744 */
      59                 :         "ACL",
      60                 :         NULL
      61                 : };
      62                 : /* }}} */
      63                 : 
      64                 : /* {{{ */
      65                 : PHP_MINIT_FUNCTION(http_request_method)
      66             220 : {
      67                 :         /* HTTP/1.1 */
      68             220 :         HTTP_LONG_CONSTANT("HTTP_METH_GET", HTTP_GET);
      69             220 :         HTTP_LONG_CONSTANT("HTTP_METH_HEAD", HTTP_HEAD);
      70             220 :         HTTP_LONG_CONSTANT("HTTP_METH_POST", HTTP_POST);
      71             220 :         HTTP_LONG_CONSTANT("HTTP_METH_PUT", HTTP_PUT);
      72             220 :         HTTP_LONG_CONSTANT("HTTP_METH_DELETE", HTTP_DELETE);
      73             220 :         HTTP_LONG_CONSTANT("HTTP_METH_OPTIONS", HTTP_OPTIONS);
      74             220 :         HTTP_LONG_CONSTANT("HTTP_METH_TRACE", HTTP_TRACE);
      75             220 :         HTTP_LONG_CONSTANT("HTTP_METH_CONNECT", HTTP_CONNECT);
      76                 :         /* WebDAV - RFC 2518 */
      77             220 :         HTTP_LONG_CONSTANT("HTTP_METH_PROPFIND", HTTP_PROPFIND);
      78             220 :         HTTP_LONG_CONSTANT("HTTP_METH_PROPPATCH", HTTP_PROPPATCH);
      79             220 :         HTTP_LONG_CONSTANT("HTTP_METH_MKCOL", HTTP_MKCOL);
      80             220 :         HTTP_LONG_CONSTANT("HTTP_METH_COPY", HTTP_COPY);
      81             220 :         HTTP_LONG_CONSTANT("HTTP_METH_MOVE", HTTP_MOVE);
      82             220 :         HTTP_LONG_CONSTANT("HTTP_METH_LOCK", HTTP_LOCK);
      83             220 :         HTTP_LONG_CONSTANT("HTTP_METH_UNLOCK", HTTP_UNLOCK);
      84                 :         /* WebDAV Versioning - RFC 3253 */
      85             220 :         HTTP_LONG_CONSTANT("HTTP_METH_VERSION_CONTROL", HTTP_VERSION_CONTROL);
      86             220 :         HTTP_LONG_CONSTANT("HTTP_METH_REPORT", HTTP_REPORT);
      87             220 :         HTTP_LONG_CONSTANT("HTTP_METH_CHECKOUT", HTTP_CHECKOUT);
      88             220 :         HTTP_LONG_CONSTANT("HTTP_METH_CHECKIN", HTTP_CHECKIN);
      89             220 :         HTTP_LONG_CONSTANT("HTTP_METH_UNCHECKOUT", HTTP_UNCHECKOUT);
      90             220 :         HTTP_LONG_CONSTANT("HTTP_METH_MKWORKSPACE", HTTP_MKWORKSPACE);
      91             220 :         HTTP_LONG_CONSTANT("HTTP_METH_UPDATE", HTTP_UPDATE);
      92             220 :         HTTP_LONG_CONSTANT("HTTP_METH_LABEL", HTTP_LABEL);
      93             220 :         HTTP_LONG_CONSTANT("HTTP_METH_MERGE", HTTP_MERGE);
      94             220 :         HTTP_LONG_CONSTANT("HTTP_METH_BASELINE_CONTROL", HTTP_BASELINE_CONTROL);
      95             220 :         HTTP_LONG_CONSTANT("HTTP_METH_MKACTIVITY", HTTP_MKACTIVITY);
      96                 :         /* WebDAV Access Control - RFC 3744 */
      97             220 :         HTTP_LONG_CONSTANT("HTTP_METH_ACL", HTTP_ACL);
      98                 :         
      99             220 :         return SUCCESS;
     100                 : }
     101                 : 
     102                 : PHP_RINIT_FUNCTION(http_request_method)
     103             219 : {
     104             219 :         HTTP_G->request.methods.custom.entries = ecalloc(1, sizeof(http_request_method_entry *));
     105                 :         
     106             219 :         if (HTTP_G->request.methods.custom.ini && *HTTP_G->request.methods.custom.ini) {
     107                 :                 HashPosition pos;
     108                 :                 HashTable methods;
     109                 :                 zval **data;
     110                 :         
     111               0 :                 zend_hash_init(&methods, 0, NULL, ZVAL_PTR_DTOR, 0);
     112               0 :                 http_parse_params(HTTP_G->request.methods.custom.ini, HTTP_PARAMS_DEFAULT, &methods);
     113               0 :                 FOREACH_HASH_VAL(pos, &methods, data) {
     114               0 :                         if (Z_TYPE_PP(data) == IS_STRING) {
     115               0 :                                 http_request_method_register(Z_STRVAL_PP(data), Z_STRLEN_PP(data));
     116                 :                         }
     117                 :                 }
     118               0 :                 zend_hash_destroy(&methods);
     119                 :         }
     120             219 :         return SUCCESS;
     121                 : }
     122                 : 
     123                 : PHP_RSHUTDOWN_FUNCTION(http_request_method)
     124             219 : {
     125                 :         int i;
     126             219 :         http_request_method_entry **ptr = HTTP_G->request.methods.custom.entries;
     127                 :         
     128             225 :         for (i = 0; i < HTTP_G->request.methods.custom.count; ++i) {
     129               6 :                 if (ptr[i]) {
     130               1 :                         http_request_method_unregister(HTTP_CUSTOM_REQUEST_METHOD_START + i);
     131                 :                 }
     132                 :         }
     133             219 :         efree(HTTP_G->request.methods.custom.entries);
     134                 :         
     135             219 :         return SUCCESS;
     136                 : }
     137                 : /* }}} */
     138                 : 
     139                 : /* {{{ char *http_request_method_name(http_request_method) */
     140                 : PHP_HTTP_API const char *_http_request_method_name(http_request_method m TSRMLS_DC)
     141              30 : {
     142              30 :         http_request_method_entry **ptr = HTTP_G->request.methods.custom.entries;
     143                 : 
     144              30 :         if (HTTP_STD_REQUEST_METHOD(m)) {
     145              27 :                 return http_request_methods[m];
     146                 :         }
     147                 : 
     148               3 :         if (    (HTTP_CUSTOM_REQUEST_METHOD(m) >= 0) && 
     149                 :                         (HTTP_CUSTOM_REQUEST_METHOD(m) < HTTP_G->request.methods.custom.count) &&
     150                 :                         (ptr[HTTP_CUSTOM_REQUEST_METHOD(m)])) {
     151               1 :                 return ptr[HTTP_CUSTOM_REQUEST_METHOD(m)]->name;
     152                 :         }
     153                 : 
     154               2 :         return http_request_methods[0];
     155                 : }
     156                 : /* }}} */
     157                 : 
     158                 : /* {{{ int http_request_method_exists(zend_bool, ulong, char *) */
     159                 : PHP_HTTP_API int _http_request_method_exists(zend_bool by_name, http_request_method id, const char *name TSRMLS_DC)
     160              96 : {
     161                 :         int i;
     162              96 :         http_request_method_entry **ptr = HTTP_G->request.methods.custom.entries;
     163                 :         
     164              96 :         if (by_name) {
     165            1190 :                 for (i = HTTP_MIN_REQUEST_METHOD; i < HTTP_MAX_REQUEST_METHOD; ++i) {
     166            1161 :                         if (!strcasecmp(name, http_request_methods[i])) {
     167              27 :                                 return i;
     168                 :                         }
     169                 :                 }
     170              94 :                 for (i = 0; i < HTTP_G->request.methods.custom.count; ++i) {
     171              75 :                         if (ptr[i] && !strcasecmp(name, ptr[i]->name)) {
     172              10 :                                 return HTTP_CUSTOM_REQUEST_METHOD_START + i;
     173                 :                         }
     174                 :                 }
     175              40 :         } else if (HTTP_STD_REQUEST_METHOD(id)) {
     176              27 :                 return id;
     177              13 :         } else if (     (HTTP_CUSTOM_REQUEST_METHOD(id) >= 0) && 
     178                 :                                 (HTTP_CUSTOM_REQUEST_METHOD(id) < HTTP_G->request.methods.custom.count) && 
     179                 :                                 (ptr[HTTP_CUSTOM_REQUEST_METHOD(id)])) {
     180               6 :                 return id;
     181                 :         }
     182                 :         
     183              26 :         return 0;
     184                 : }
     185                 : /* }}} */
     186                 : 
     187                 : /* {{{ int http_request_method_register(char *) */
     188                 : PHP_HTTP_API int _http_request_method_register(const char *method_name, int method_name_len TSRMLS_DC)
     189               6 : {
     190                 :         int i, meth_num;
     191                 :         char *http_method, *method, *mconst;
     192               6 :         http_request_method_entry **ptr = HTTP_G->request.methods.custom.entries;
     193                 :         
     194               6 :         if (!HTTP_IS_CTYPE(alpha, *method_name)) {
     195               0 :                 http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Request method does not start with a character (%s)", method_name);
     196               0 :                 return 0;
     197                 :         }
     198                 :         
     199               6 :         if (http_request_method_exists(1, 0, method_name)) {
     200               0 :                 http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Request method does already exist (%s)", method_name);
     201               0 :                 return 0;
     202                 :         }
     203                 :         
     204               6 :         method = emalloc(method_name_len + 1);
     205               6 :         mconst = emalloc(method_name_len + 1);
     206              22 :         for (i = 0; i < method_name_len; ++i) {
     207              16 :                 switch (method_name[i]) {
     208                 :                         case '-':
     209               0 :                                 method[i] = '-';
     210               0 :                                 mconst[i] = '_';
     211               0 :                                 break;
     212                 :                         
     213                 :                         default:
     214              16 :                                 if (!HTTP_IS_CTYPE(alnum, method_name[i])) {
     215               0 :                                         efree(method);
     216               0 :                                         efree(mconst);
     217               0 :                                         http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Request method contains illegal characters (%s)", method_name);
     218               0 :                                         return 0;
     219                 :                                 }
     220              16 :                                 mconst[i] = method[i] = HTTP_TO_CTYPE(upper, method_name[i]);
     221                 :                                 break;
     222                 :                 }
     223                 :         }
     224               6 :         method[method_name_len] = '\0';
     225               6 :         mconst[method_name_len] = '\0';
     226                 :         
     227               6 :         ptr = erealloc(ptr, sizeof(http_request_method_entry *) * (HTTP_G->request.methods.custom.count + 1));
     228               6 :         HTTP_G->request.methods.custom.entries = ptr;
     229               6 :         ptr[HTTP_G->request.methods.custom.count] = emalloc(sizeof(http_request_method_entry));
     230               6 :         ptr[HTTP_G->request.methods.custom.count]->name = method;
     231               6 :         ptr[HTTP_G->request.methods.custom.count]->cnst = mconst;
     232               6 :         meth_num = HTTP_CUSTOM_REQUEST_METHOD_START + HTTP_G->request.methods.custom.count++;
     233                 : 
     234               6 :         method_name_len = spprintf(&http_method, 0, "HTTP_METH_%s", mconst);
     235               6 :         zend_register_long_constant(http_method, method_name_len + 1, meth_num, CONST_CS, http_module_number TSRMLS_CC);
     236               6 :         efree(http_method);
     237                 :         
     238                 : #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL) && !defined(WONKY)
     239               6 :         method_name_len = spprintf(&http_method, 0, "METH_%s", mconst);
     240               6 :         zend_declare_class_constant_long(http_request_object_ce, http_method, method_name_len, meth_num TSRMLS_CC);
     241               6 :         efree(http_method);
     242                 : #endif
     243                 :         
     244               6 :         return meth_num;
     245                 : }
     246                 : /* }}} */
     247                 : 
     248                 : /* {{{ STATUS http_request_method_unregister(int) */
     249                 : PHP_HTTP_API STATUS _http_request_method_unregister(int method TSRMLS_DC)
     250               6 : {
     251                 :         char *http_method;
     252                 :         int method_len;
     253               6 :         http_request_method_entry **ptr = HTTP_G->request.methods.custom.entries;
     254                 :         
     255               6 :         if (HTTP_STD_REQUEST_METHOD(method)) {
     256               0 :                 http_error_ex(HE_WARNING, HTTP_E_REQUEST_METHOD, "Standard request methods cannot be unregistered");
     257               0 :                 return FAILURE;
     258                 :         }
     259                 : 
     260               6 :         if (    (HTTP_CUSTOM_REQUEST_METHOD(method) < 0) ||
     261                 :                         (HTTP_CUSTOM_REQUEST_METHOD(method) > HTTP_G->request.methods.custom.count) ||
     262                 :                         (!ptr[HTTP_CUSTOM_REQUEST_METHOD(method)])) {
     263               0 :                 http_error_ex(HE_NOTICE, HTTP_E_REQUEST_METHOD, "Custom request method with id %d does not exist", method);
     264               0 :                 return FAILURE;
     265                 :         }
     266                 :         
     267                 : #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL) && !defined(WONKY)
     268               6 :         method_len = spprintf(&http_method, 0, "METH_%s", ptr[HTTP_CUSTOM_REQUEST_METHOD(method)]->cnst);
     269               6 :         if (SUCCESS != zend_hash_del(&http_request_object_ce->constants_table, http_method, method_len + 1)) {
     270               0 :                 http_error_ex(HE_NOTICE, HTTP_E_REQUEST_METHOD, "Could not unregister request method: HttpRequest::%s", http_method);
     271               0 :                 efree(http_method);
     272               0 :                 return FAILURE;
     273                 :         }
     274               6 :         efree(http_method);
     275                 : #endif
     276                 :         
     277               6 :         method_len = spprintf(&http_method, 0, "HTTP_METH_%s", ptr[HTTP_CUSTOM_REQUEST_METHOD(method)]->cnst);
     278               6 :         if (SUCCESS != zend_hash_del(EG(zend_constants), http_method, method_len + 1)) {
     279               0 :                 http_error_ex(HE_NOTICE, HTTP_E_REQUEST_METHOD, "Could not unregister request method: %s", http_method);
     280               0 :                 efree(http_method);
     281               0 :                 return FAILURE;
     282                 :         }
     283               6 :         efree(http_method);
     284                 :         
     285               6 :         efree(ptr[HTTP_CUSTOM_REQUEST_METHOD(method)]->name);
     286               6 :         efree(ptr[HTTP_CUSTOM_REQUEST_METHOD(method)]->cnst);
     287               6 :         efree(ptr[HTTP_CUSTOM_REQUEST_METHOD(method)]);
     288               6 :         ptr[HTTP_CUSTOM_REQUEST_METHOD(method)] = NULL;
     289                 :         
     290               6 :         return SUCCESS;
     291                 : }
     292                 : /* }}} */
     293                 : 
     294                 : /*
     295                 :  * Local variables:
     296                 :  * tab-width: 4
     297                 :  * c-basic-offset: 4
     298                 :  * End:
     299                 :  * vim600: noet sw=4 ts=4 fdm=marker
     300                 :  * vim<600: noet sw=4 ts=4
     301                 :  */
     302                 : 

Generated by: LTP GCOV extension version 1.5