记一次file_get_contents报failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request的错...

本文介绍了一种常见的问题:由于URL中包含空格导致HTTP请求失败并返回400错误。通过分析问题原因及尝试多种解决方法后,最终采用urlencode函数对可能包含空格的参数进行编码,成功解决了该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不能用此函数获取网页内容,会报failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request的错,但是手动执行该URL的时候就可以。

网上查了很多解决办法,都不可以不行。

包括修改user_agent=”Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)” ,

改换curl

1  public function geturldata($url) { 
2         $ch = curl_init(); 
3         curl_setopt ($ch, CURLOPT_URL, $url); 
4         curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
5         curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,10); 
6         $content = curl_exec($ch);
7         return $content;
8 } 

或者是增加参数使函数不报错等方法。

1 $context = stream_context_create(array(
2   'http' => array(
3      'ignore_errors'=>true,
4      'method'=>'GET'
5      // for more options check http://www.php.net/manual/en/context.http.php
6    )
7 ));
8 $response = json_decode(file_get_contents($url, false, $context));

最后经过观察参数发现,我的URL其中一个参数中间是有空格的。

导致URL断掉了,所以不能执行。

所以我把可能会有空格的参数都加上了urlencode就可以了。

转载于:https://www.cnblogs.com/lotus-white/p/9110513.html

/** copyright Copyright © 2009-2025 Shenzhen TP-LINK Technologies Co.Ltd. file mult_plex_web.h brief Multi-plex implementation of httpd author An Ran anran@tp-link.com.hk version 1.0.0 date 14Aug25 */ // /* INCLUDE FILES */ // #include “mult_plex_web.h” // /* DEFINES */ // // /* TYPES */ // // /* EXTERN_PROTOTYPES */ // // /* LOCAL_PROTOTYPES */ // // /* VARIABLES */ // // /* LOCAL_FUNCTIONS */ // /** fn static int check_http_method(const char *buffer) brief Check if the HTTP request method is supported param[in] const char *buffer return 0 Other method, 1 Get method, 2 Post method note */ static int check_http_method(const char buffer) { if (0 == strncmp(buffer, "GET ", 4)) { / Get method / return 1; } else if (0 == strncmp(buffer, "POST ", 5)) { / Post method / return 2; } else { / Other method */ return 0; } } /** fn static void send_headers(int client_socket, int status, const char *status_msg, const char *content_type, long content_length) brief Send HTTP response headers param[in] client_socket Socket descriptor status HTTP status code status_msg The text description corresponding to the status code content_type The MIME type of the response content content_length The length of the bytes in the response body note */ void send_headers(int client_socket, int status, const char *status_msg, const char content_type, long content_length) { / Buffer */ char headers[BUFFER_SIZE]; snprintf(headers, sizeof(headers), “HTTP/1.1 %d %s\r\n” “Server: Simple-C-WebServer\r\n” “Content-Type: %s\r\n” “Content-Length: %ld\r\n” “Connection: close\r\n” “\r\n”, status, status_msg, content_type, content_length); send(client_socket, headers, strlen(headers), 0); } /** fn static void send_error(int client_socket, int status, const char *status_msg, const char *message) brief Send an error response param[in] client_socket Socket descriptor status HTTP status code status_msg The text description corresponding to the status code content_type Customize error details note */ void send_error(int client_socket, int status, const char *status_msg, const char message) { / Buffer */ char response[BUFFER_SIZE]; /* Records the number of bytes that have been written to the buffer at the moment*/ int length = 0; length = snprintf(response, sizeof(response), “%d %s” “ %d %s %s ”, status, status_msg, status, status_msg, message); send_headers(client_socket, status, status_msg, “text/html”, length); send(client_socket, response, length, 0); } /** fn static const char *get_mime_type(const char *filename) brief Get the MIME type of the file param[in] filename Full file name or file path note */ static const char *get_mime_type(const char filename) { / A pointer to the starting position of the extension in the file name */ const char *ext = strrchr(filename, ‘.’); if (!ext) { return “application/octet-stream”; } if (strcmp(ext, “.html”) == 0 || strcmp(ext, “.htm”) == 0) { return “text/html”; } if (strcmp(ext, “.txt”) == 0) { return “text/plain”; } if (strcmp(ext, “.css”) == 0) { return “text/css”; } if (strcmp(ext, “.js”) == 0) { return “application/javascript”; } if (strcmp(ext, “.jpg”) == 0 || strcmp(ext, “.jpeg”) == 0) { return “image/jpeg”; } if (strcmp(ext, “.png”) == 0) { return “image/png”; } if (strcmp(ext, “.gif”) == 0) { return “image/gif”; } if (strcmp(ext, “.pdf”) == 0) { return “application/pdf”; } if (strcmp(ext, “.zip”) == 0) { return “application/zip”; } return “application/octet-stream”; } /** fn static void send_file(int client_socket, const char *filename) brief Send the file content param[in] client_socket Socket descriptor filename The requested file path note / static void send_file(int client_socket, const char filename) { / file_stat Store file metadata dir A directory flow pointer that is used to iterate \ through the contents of the catalog response HTML response buffer entry Catalog entry information length Records the number of bytes that have been \ written to the buffer at the moment path Temporarily stores the full path to the directory entry entry_stat Stores the metadata of individual files within a directory size_str File size formatting string fd File descriptor buffer File read/write buffer bytes_read Records the number of bytes per read() read */ struct stat file_stat = {0}; struct stat entry_stat = {0}; char response[BUFFER_SIZE * 4]; char path[PATH_MAX] = {0}; char buffer[BUFFER_SIZE]; char size_str[20] = {0}; int length = 0; int fd = -1; ssize_t bytes_read = 0; DIR *dir = NULL; const char *mime_type = NULL; struct dirent *entry = NULL; if (0 > stat(filename, &file_stat)) { send_error(client_socket, 404, “Not Found”, “File not found”); return; } if (S_ISDIR(file_stat.st_mode)) { /* If it’s a catalog, list the contents of the catalog */ dir = opendir(filename); if (!dir) { send_error(client_socket, 403, “Forbidden”, “Cannot list directory”); return; } length = snprintf(response, sizeof(response), “Index of %s” “ Index of %s ”, filename, filename); while (NULL != (entry = readdir(dir))) { /* Skip hidden files and current/parent directories */ if (‘.’ == entry->d_name[0]) { continue; } snprintf(path, sizeof(path), “%s/%s”, filename, entry->d_name); stat(path, &entry_stat); if (S_ISDIR(entry_stat.st_mode)) { strcpy(size_str, “<DIR>”); } else { snprintf(size_str, sizeof(size_str), “%ld bytes”, entry_stat.st_size); } length += snprintf(response + length, sizeof(response) - length, “ <a href="%s">%s - %s”, entry->d_name, entry->d_name, size_str); } length += snprintf(response + length, sizeof(response) - length, “”); closedir(dir); send_headers(client_socket, 200, “OK”, “text/html”, length); send(client_socket, response, length, 0); return; } /* Send the file content */ fd = open(filename, O_RDONLY); if (0 > fd) { send_error(client_socket, 403, “Forbidden”, “Cannot open file”); return; } /* Send HTTP headers */ mime_type = get_mime_type(filename); send_headers(client_socket, 200, “OK”, mime_type, file_stat.st_size); /* Send the file content */ while (0 < (bytes_read = read(fd, buffer, sizeof(buffer)))) { send(client_socket, buffer, bytes_read, 0); } close(fd); } /** fn static void url_decode(const char *src, char *dest, size_t dest_size) brief URL decoding param[in] src Temporarily store the original path dest Stores the decoded string dest_size Store the space size of the decoded string param[out] dest Stores the decoded string note */ static void url_decode(const char *src, char dest, size_t dest_size) { / Space maximum */ char *end = dest + dest_size - 1; while (*src && dest < end) { if (*src == ‘%’ && isxdigit(src[1]) && isxdigit(src[2])) { char hex[3] = {src[1], src[2], ‘\0’}; *dest++ = (char)strtol(hex, NULL, 16); src += 3; } else if (*src == ‘+’) { *dest++ = ’ '; src++; } else { *dest++ = *src++; } } *dest = ‘\0’; } /** fn static int parse_request_path(const char *buffer, char *decoded_path, size_t decoded_size) brief Check the path format and URL process param[in] buffer Received data buffer decoded_path Stores the decoded string decoded_size Store the space size of the decoded string note */ static int parse_request_path(const char *buffer, char decoded_path, size_t decoded_size) { / Temporarily store the original path and path length */ char raw_path[BUFFER_SIZE]; size_t path_len; /* Skip the "GET " */ const char *path_start = buffer + 4; /* Check if the path in the HTTP header is formatted correctly */ const char *path_end = strchr(path_start, ’ '); if (!path_end) { return -1; } /* Temporarily store the original path */ path_len = path_end - path_start; if (path_len >= sizeof(raw_path)) { return -1; } memcpy(raw_path, path_start, path_len); raw_path[path_len] = ‘\0’; /* URL decoding */ url_decode(raw_path, decoded_path, decoded_size); return 0; } /** fn static int build_safe_path(const char *root_dir, const char *decoded_path, char *full_path, size_t full_path_size) brief Build a secure output directory param[in] root_dir Root path decoded_path Stores the decoded string full_path The full path of the output full_path_size Buffer size note */ static int build_safe_path(const char *root_dir, const char *decoded_path, char full_path, size_t full_path_size) { / Prevent directory traversal attacks */ if (strstr(decoded_path, “…”)) { return -1; } snprintf(full_path, full_path_size, “%s%s”, root_dir, decoded_path); /* Automatically add Index.html */ if (full_path[strlen(full_path) - 1] == ‘/’) { strncat(full_path, “Index.html”, full_path_size - strlen(full_path) - 1); } return 0; } /** fn static void handle_get_request(int client_socket, char *buffer) brief Process GET requests param[in] client_socket client socket buffer Received data buffer note */ static void handle_get_request(int client_socket, char buffer) { / *decoded_path Stores the decoded string *full_path The full path of the output */ char decoded_path[BUFFER_SIZE]; char full_path[BUFFER_SIZE]; /* URL process */ if (0 != parse_request_path(buffer, decoded_path, sizeof(decoded_path))) { send_error(client_socket, 400, “Bad Request”, “Invalid request”); return; } /* Build a safe path */ if (0 != build_safe_path(ROOT_DIR, decoded_path, full_path, sizeof(full_path))) { send_error(client_socket, 403, “Forbidden”, “Directory traversal not allowed”); return; } /* Send files */ printf(“Request: %s -> %s\n”, decoded_path, full_path); send_file(client_socket, full_path); return; } /** fn static void handle_post_request(int client_socket, char *buffer, ssize_t bytes_read) brief Process POST requests param[in] client_socket client socket buffer Received data buffer bytes_read Received data length note */ static void handle_post_request(int client_socket, char *buffer, ssize_t bytes_read) { /** content_length_start Look for the “Content-Length” field in the HTTP response header body_start Look for the “Message body” field in the HTTP response header post_data Stored the post data response Respond to messages total_read copy the length of the data has been read content_length Expected message body length body_len Actual message body length n The size of the bytes read */ char *content_length_start = NULL; char *body_start = NULL; char *post_data = NULL; const char *response = NULL; int total_read = 0; int content_length = 0; int body_len = 0; int n = 0; /* get Content-Length */ content_length_start = strstr(buffer, "Content-Length: "); if (!content_length_start) { perror(“get Content-Length failed”); exit(EXIT_FAILURE); } /* skip "Content-Length: "*/ content_length_start += 16; content_length = atoi(content_length_start); /* read POST data */ post_data = malloc(content_length + 1); if (!post_data) { perror(“get POST data failed”); exit(EXIT_FAILURE); } body_start = strstr(buffer, “\r\n\r\n”); /* Copy the data in the buffer to your local location */ if (body_start) { body_start += 4; body_len = bytes_read - (body_start - buffer); memcpy(post_data, body_start, body_len); total_read = body_len; } /* Read the remaining data */ while (total_read < content_length) { n = recv(client_socket, post_data + total_read, content_length - total_read, 0); if (n <= 0) { break; } total_read += n; } post_data[total_read] = ‘\0’; /* Print the POST data */ printf(“Received POST data: %s\n”, post_data); /* Send the response */ response = “{“callback”:“congratulations!”}”; send_headers(client_socket, 200, “OK”, “application/json”, strlen(response)); send(client_socket, response, strlen(response), 0); free(post_data); } // /* PUBLIC_FUNCTIONS / // /* fn void handle_request(int client_socket) brief Handle HTTP requests param[in] int client_socket Socket file descriptor note / void handle_request(int client_socket) { / *buffer Stores the decoded string *bytes_read Received data length *method Method type */ char buffer[BUFFER_SIZE]; int method = 0; ssize_t bytes_read = recv(client_socket, buffer, sizeof(buffer) - 1, 0); /* Receive data fails to be handled */ if (0 >= bytes_read) { return; } buffer[bytes_read] = ‘\0’; /* Check the HTTP method / method = check_http_method(buffer); if (0 == method) { send_error(client_socket, 501, “Not Implemented”, “Only GET and POST methods are supported”); return; } else if (1 == method ) { / Process GET requests / handle_get_request(client_socket, buffer); return; } else if (2 == method) { / Process POST requests */ handle_post_request(client_socket, buffer, bytes_read); return; } } // /* GLOBAL_FUNCTIONS */ // int main() { /** server_socket The server listens to the socket opt Socket option value server_addr Server address information max_ser_socket */ int server_socket = -1; int opt = 1; struct sockaddr_in server_addr; int max_ser_socket = -1; fd_set rdset, rdtmp; FD_ZERO(&rdset); /* Create a server socket / server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket < 0) { perror(“socket creation failed”); exit(EXIT_FAILURE); } / Set SO_REUSEADDR options / if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { perror(“setsockopt failed”); close(server_socket); exit(EXIT_FAILURE); } / Bind addresses and ports / memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(PORT); if (0 > bind(server_socket, (struct sockaddr )&server_addr, sizeof(server_addr)) ) { perror(“bind failed”); close(server_socket); exit(EXIT_FAILURE); } / Start listening / if (0 > listen(server_socket, BACKLOG)) { perror(“listen failed”); close(server_socket); exit(EXIT_FAILURE); } printf(“Server running on port %d, serving files from %s\n”, PORT, ROOT_DIR); printf(“Open http://localhost in your browser\n”); max_ser_socket = server_socket; FD_SET(server_socket, &rdset); / Main loop: Accept and process connections / while (1) { / * client_addr Stores the client’s address information * client_addr_len Used to store the length of client_addr structure * client_socket Store the socket descriptor of the client * fd Traverse the file descriptor collection / int fd = 0; struct sockaddr_in client_addr; socklen_t client_addr_len = sizeof(client_addr); int client_socket = -1; / A copy of rdset (a collection of read file descriptors). / rdtmp = rdset; / Call select listens for file descriptors in the rdtmp collection / select(max_ser_socket + 1, &rdtmp, NULL, NULL, NULL); / Loop through each file descriptor from 0 to max_ser_socket / for (; fd < max_ser_socket + 1; fd++) { / There is a reading event / if (FD_ISSET(fd, &rdtmp)) { / New connections / if (fd == server_socket) { / Accept the connection */ client_socket = accept(server_socket, (struct sockaddr )&client_addr, &client_addr_len); if (0 > client_socket) { perror(“accept failed!”); close(client_socket); continue; } / Add the new client socket and update the max_ser_socket / FD_SET(client_socket, &rdset); max_ser_socket = client_socket > max_ser_socket ? client_socket : max_ser_socket; } else { / Connected clients */ handle_request(fd); close(fd); FD_CLR(fd, &rdset); } } } } close(server_socket); return 0; }给我生成一个以上代码的设计流程图,要抽象出来实现的功能方法和目的
最新发布
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值