⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http_fopen_wrapper.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	php_stream_write(stream, "\r\n", sizeof("\r\n")-1);	/* Request content, such as for POST requests */	if (context && php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS &&		Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) {		php_stream_write(stream, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval));		php_stream_write(stream, "\r\n\r\n", sizeof("\r\n\r\n")-1);	}	location[0] = '\0';	/* 	 * We need to read the HTTP response header one-by-one, because	 * the original author did not know about MSG_PEEK.	 * The chunk_size will be reset later, once we have read the	 * header completely.	 */	if (options & STREAM_WILL_CAST)		chunk_size = php_stream_set_chunk_size(stream, 1);	if (!header_init && FAILURE == zend_hash_find(EG(active_symbol_table),				"http_response_header", sizeof("http_response_header"), (void **) &response_header)) {		header_init = 1;	}	if (header_init) {		zval *tmp;		MAKE_STD_ZVAL(tmp);		array_init(tmp);		ZEND_SET_SYMBOL(EG(active_symbol_table), "http_response_header", tmp);			zend_hash_find(EG(active_symbol_table),				"http_response_header", sizeof("http_response_header"), (void **) &response_header);	}	if (!php_stream_eof(stream)) {		size_t tmp_line_len;		/* get response header */		if (php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len) != NULL) {			zval *http_response;			int response_code;			MAKE_STD_ZVAL(http_response);			ZVAL_NULL(http_response);			if (tmp_line_len > 9) {				response_code = atoi(tmp_line + 9);			} else {				response_code = 0;			}			switch(response_code) {				case 200:				case 206: /* partial content */				case 302:				case 301:					reqok = 1;					break;				case 403:					php_stream_notify_error(context, PHP_STREAM_NOTIFY_AUTH_RESULT,							tmp_line, response_code);					break;				default:					/* safety net in the event tmp_line == NULL */					if (!tmp_line_len) {						tmp_line[0] = '\0';					}					php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE,							tmp_line, response_code);			}						Z_STRLEN_P(http_response) = tmp_line_len;			Z_STRVAL_P(http_response) = estrndup(tmp_line, Z_STRLEN_P(http_response));			if (Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=='\n') {				Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=0;				Z_STRLEN_P(http_response)--;				if (Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=='\r') {					Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=0;					Z_STRLEN_P(http_response)--;				}			}			Z_TYPE_P(http_response) = IS_STRING;			zend_hash_next_index_insert(Z_ARRVAL_PP(response_header), &http_response, sizeof(zval *), NULL);		}	} else {		php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed, unexpected end of socket!");		goto out;	}		/* read past HTTP headers */		http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE);	while (!body && !php_stream_eof(stream)) {		size_t http_header_line_length;		if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) && *http_header_line != '\n' && *http_header_line != '\r') {			char *e = http_header_line + http_header_line_length - 1;			while (*e == '\n' || *e == '\r') {				e--;			}			http_header_line_length = e - http_header_line + 1;			http_header_line[http_header_line_length] = '\0';			if (!strncasecmp(http_header_line, "Location: ", 10)) {				strlcpy(location, http_header_line + 10, sizeof(location));			} else if (!strncasecmp(http_header_line, "Content-Type: ", 14)) {				php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_line + 14, 0);			} else if (!strncasecmp(http_header_line, "Content-Length: ", 16)) {				file_size = atoi(http_header_line + 16);				php_stream_notify_file_size(context, file_size, http_header_line, 0);			}			if (http_header_line[0] == '\0') {				body = 1;			} else {				zval *http_header;				MAKE_STD_ZVAL(http_header);				ZVAL_STRINGL(http_header, http_header_line, http_header_line_length, 1);								zend_hash_next_index_insert(Z_ARRVAL_PP(response_header), &http_header, sizeof(zval *), NULL);			}		} else {			break;		}	}		if (!reqok || location[0] != '\0')	{				if (location[0] != '\0')			php_stream_notify_info(context, PHP_STREAM_NOTIFY_REDIRECTED, location, 0);		php_stream_close(stream);		stream = NULL;		if (location[0] != '\0')	{			zval *entry, **entryp;			char new_path[HTTP_HEADER_BLOCK_SIZE];			char loc_path[HTTP_HEADER_BLOCK_SIZE];			*new_path='\0';			if (strlen(location)<8 || (strncasecmp(location, "http://", sizeof("http://")-1) && 							strncasecmp(location, "https://", sizeof("https://")-1) && 							strncasecmp(location, "ftp://", sizeof("ftp://")-1) && 							strncasecmp(location, "ftps://", sizeof("ftps://")-1))) 			{				if (*location != '/') {					if (*(location+1) != '\0' && resource->path) {								char *s = strrchr(resource->path, '/');						if (!s) {							s = resource->path;							if (!s[0]) {								efree(s);								s = resource->path = estrdup("/");							} else {								*s = '/';							}						}						s[1] = '\0'; 						if (resource->path && *(resource->path) == '/' && *(resource->path + 1) == '\0') {							snprintf(loc_path, sizeof(loc_path) - 1, "%s%s", resource->path, location);						} else {							snprintf(loc_path, sizeof(loc_path) - 1, "%s/%s", resource->path, location);						}					} else {						snprintf(loc_path, sizeof(loc_path) - 1, "/%s", location);					}				} else {					strlcpy(loc_path, location, sizeof(loc_path));				}				if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) {					snprintf(new_path, sizeof(new_path) - 1, "%s://%s:%d%s", resource->scheme, resource->host, resource->port, loc_path);				} else {					snprintf(new_path, sizeof(new_path) - 1, "%s://%s%s", resource->scheme, resource->host, loc_path);				}			} else {				strlcpy(new_path, location, sizeof(new_path));			}			php_url_free(resource);			/* check for invalid redirection URLs */			if ((resource = php_url_parse(new_path)) == NULL) {				php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Invalid redirect url! %s", new_path);				goto out;			}#define CHECK_FOR_CNTRL_CHARS(val) {	\	if (val) {	\		unsigned char *s, *e;	\		int l;	\		l = php_url_decode(val, strlen(val));	\		s = val; e = s + l;	\		while (s < e) {	\			if (iscntrl(*s)) {	\				php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Invalid redirect url! %s", new_path);	\				goto out;	\			}	\			s++;	\		}	\	}	\}	\			/* check for control characters in login, password & path */			if (strncasecmp(new_path, "http://", sizeof("http://") - 1) || strncasecmp(new_path, "https://", sizeof("https://") - 1)) {				CHECK_FOR_CNTRL_CHARS(resource->user)				CHECK_FOR_CNTRL_CHARS(resource->pass)				CHECK_FOR_CNTRL_CHARS(resource->path)			}			stream = php_stream_url_wrap_http_ex(NULL, new_path, mode, options, opened_path, context, --redirect_max, 0 STREAMS_CC TSRMLS_CC);			if (stream && stream->wrapperdata)	{				entryp = &entry;				MAKE_STD_ZVAL(entry);				ZVAL_EMPTY_STRING(entry);				zend_hash_next_index_insert(Z_ARRVAL_PP(response_header), entryp, sizeof(zval *), NULL);				zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream->wrapperdata));				while (zend_hash_get_current_data(Z_ARRVAL_P(stream->wrapperdata), (void **)&entryp) == SUCCESS) {					zval_add_ref(entryp);					zend_hash_next_index_insert(Z_ARRVAL_PP(response_header), entryp, sizeof(zval *), NULL);					zend_hash_move_forward(Z_ARRVAL_P(stream->wrapperdata));				}				zval_dtor(stream->wrapperdata);				FREE_ZVAL(stream->wrapperdata);			}		} else {			php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed! %s", tmp_line);		}	}out:	if (http_header_line)		efree(http_header_line);	if (scratch)		efree(scratch);	if (resource) {		php_url_free(resource);	}	if (stream) {		if (header_init) {			stream->wrapperdata = *response_header;			zval_add_ref(response_header);		}		php_stream_notify_progress_init(context, 0, file_size);		/* Restore original chunk size now that we're done with headers (if applicable) */		if (options & STREAM_WILL_CAST)			php_stream_set_chunk_size(stream, chunk_size);		/* restore the users auto-detect-line-endings setting */		stream->flags |= eol_detect;		/* as far as streams are concerned, we are now at the start of		 * the stream */		stream->position = 0;	}	return stream;}php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC){	return php_stream_url_wrap_http_ex(wrapper, path, mode, options, opened_path, context, PHP_URL_REDIRECT_MAX, 1 STREAMS_CC TSRMLS_CC);}static int php_stream_http_stream_stat(php_stream_wrapper *wrapper,		php_stream *stream,		php_stream_statbuf *ssb		TSRMLS_DC){	/* one day, we could fill in the details based on Date: and Content-Length:	 * headers.  For now, we return with a failure code to prevent the underlying	 * file's details from being used instead. */	return -1;}static php_stream_wrapper_ops http_stream_wops = {	php_stream_url_wrap_http,	NULL, /* stream_close */	php_stream_http_stream_stat,	NULL, /* stat_url */	NULL, /* opendir */	"HTTP"};php_stream_wrapper php_stream_http_wrapper =	{	&http_stream_wops,	NULL,	1 /* is_url */};/* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -