Skip to content

Commit 2624022

Browse files
committed
fix ithewei#179: 中文路径
1 parent 7af5229 commit 2624022

File tree

10 files changed

+84
-39
lines changed

10 files changed

+84
-39
lines changed

cpputil/hurl.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,24 @@ static inline bool is_unambiguous(char c) {
3535
c == '~';
3636
}
3737

38+
static inline bool char_in_str(char c, const char* str) {
39+
const char* p = str;
40+
while (*p && *p != c) ++p;
41+
return *p != '\0';
42+
}
43+
3844
static inline unsigned char hex2i(char hex) {
3945
return hex <= '9' ? hex - '0' :
4046
hex <= 'F' ? hex - 'A' + 10 : hex - 'a' + 10;
4147
}
4248

43-
std::string url_escape(const char* istr) {
49+
std::string url_escape(const char* istr, const char* unescaped_chars) {
4450
std::string ostr;
4551
static char tab[] = "0123456789ABCDEF";
4652
const unsigned char* p = reinterpret_cast<const unsigned char*>(istr);
4753
char szHex[4] = "%00";
4854
while (*p != '\0') {
49-
if (is_unambiguous(*p)) {
55+
if (is_unambiguous(*p) || char_in_str(*p, unescaped_chars)) {
5056
ostr += *p;
5157
}
5258
else {

cpputil/hurl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#include "hexport.h"
77

8-
HV_EXPORT std::string url_escape(const char* istr);
8+
HV_EXPORT std::string url_escape(const char* istr, const char* unescaped_chars = "");
99
HV_EXPORT std::string url_unescape(const char* istr);
1010

1111
#endif // HV_URL_H_

examples/curl.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include "http_client.h"
11+
#include "hurl.h"
1112

1213
#ifdef _MSC_VER
1314
#include "misc/win32_getopt.h"
@@ -262,7 +263,8 @@ int main(int argc, char* argv[]) {
262263
req.method = HTTP_POST;
263264
}
264265
}
265-
req.url = url;
266+
// http://127.0.0.1:8080@user:pswd/path?k1=v1&k2=v2#fragment
267+
req.url = url_escape(url, ":/@?=&#");
266268
req.http_cb = [](HttpMessage* res, http_parser_state state, const char* data, size_t size) {
267269
if (state == HP_HEADERS_COMPLETE) {
268270
if (verbose) {

getting_started.sh

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ cmd="bin/curl -v localhost:8080" && run_cmd
3333

3434
# http indexof service
3535
cmd="bin/curl -v localhost:8080/downloads/" && run_cmd
36+
cmd="bin/curl -v localhost:8080/downloads/中文.html" && run_cmd
3637

3738
# http api service
3839
cmd="bin/curl -v localhost:8080/paths" && run_cmd

html/downloads/中文.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>中文测试</title>
6+
</head>
7+
<body>
8+
<center><h1> 欢迎使用 <a href="https://github.com/ithewei/libhv.git">libhv</a> </h1></center>
9+
</body>
10+
</html>

html/index.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<!DOCTYPE html>
22
<html>
33
<head>
4-
<title>httpd</title>
4+
<title>libhv</title>
55
</head>
66
<body>
7-
<center><h1>Welcome to httpd!</h1></center>
7+
<center><h1> Welcome to <a href="https://github.com/ithewei/libhv.git">libhv</a> </h1></center>
88
</body>
99
</html>

http/HttpMessage.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -547,22 +547,22 @@ void HttpRequest::ParseUrl() {
547547
FillHost(host_.c_str(), port_);
548548
// path
549549
if (parser.field_set & (1<<UF_PATH)) {
550-
const char* sp = url.c_str() + parser.field_data[UF_PATH].off;
551-
char* ep = (char*)(sp + parser.field_data[UF_PATH].len);
552-
char ev = *ep;
553-
*ep = '\0';
554-
path = url_unescape(sp);
555-
if (ev != '\0') {
556-
*ep = ev;
557-
path += ep;
558-
}
550+
path = url.substr(parser.field_data[UF_PATH].off);
559551
}
560552
// query
561553
if (parser.field_set & (1<<UF_QUERY)) {
562554
parse_query_params(url.c_str()+parser.field_data[UF_QUERY].off, query_params);
563555
}
564556
}
565557

558+
std::string HttpRequest::Path() {
559+
const char* s = path.c_str();
560+
const char* e = s;
561+
while (*e && *e != '?' && *e != '#') ++e;
562+
std::string path_no_query(s, e);
563+
return url_unescape(path_no_query.c_str());
564+
}
565+
566566
void HttpRequest::FillHost(const char* host, int port) {
567567
if (headers.find("Host") == headers.end()) {
568568
if (port == 0 ||

http/HttpMessage.h

+3-6
Original file line numberDiff line numberDiff line change
@@ -463,13 +463,10 @@ class HV_EXPORT HttpRequest : public HttpMessage {
463463
// url -> structed url
464464
void ParseUrl();
465465

466+
// /path?query#fragment
467+
std::string FullPath() { return path; }
466468
// /path
467-
std::string Path() {
468-
const char* s = path.c_str();
469-
const char* e = s;
470-
while (*e && *e != '?' && *e != '#') ++e;
471-
return std::string(s, e);
472-
}
469+
std::string Path();
473470

474471
// ?query_params
475472
template<typename T>

http/server/http_page.cpp

+28-11
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ void make_http_status_page(http_status status_code, std::string& page) {
2424
}
2525

2626
void make_index_of_page(const char* dir, std::string& page, const char* url) {
27-
std::list<hdir_t> dirs;
28-
listdir(dir, dirs);
2927
char c_str[1024] = {0};
3028
snprintf(c_str, sizeof(c_str), R"(<!DOCTYPE html>
3129
<html>
@@ -35,26 +33,41 @@ void make_index_of_page(const char* dir, std::string& page, const char* url) {
3533
<body>
3634
<h1>Index of %s</h1>
3735
<hr>
38-
<pre>
3936
)", url, url);
4037
page += c_str;
38+
39+
page += " <table border=\"0\">\n";
40+
page += R"( <tr>
41+
<th align="left" width="30%">Name</th>
42+
<th align="left" width="20%">Date</th>
43+
<th align="left" width="20%">Size</th>
44+
</tr>
45+
)";
46+
47+
#define _ADD_TD_(page, td) \
48+
page += " <td>"; \
49+
page += td; \
50+
page += "</td>\n"; \
51+
52+
std::list<hdir_t> dirs;
53+
listdir(dir, dirs);
4154
for (auto& item : dirs) {
4255
if (item.name[0] == '.' && item.name[1] == '\0') continue;
56+
page += " <tr>\n";
4357
int len = strlen(item.name) + (item.type == 'd');
4458
// name
4559
snprintf(c_str, sizeof(c_str), "<a href=\"%s%s\">%s%s</a>",
4660
item.name,
4761
item.type == 'd' ? "/" : "",
4862
len < AUTOINDEX_FILENAME_MAXLEN ? item.name : std::string(item.name, item.name+AUTOINDEX_FILENAME_MAXLEN-4).append("...").c_str(),
4963
item.type == 'd' ? "/" : "");
50-
page += c_str;
64+
_ADD_TD_(page, c_str)
5165
if (strcmp(item.name, "..") != 0) {
5266
// mtime
5367
struct tm* tm = localtime(&item.mtime);
54-
snprintf(c_str, sizeof(c_str), "%04d-%02d-%02d %02d:%02d:%02d ",
68+
snprintf(c_str, sizeof(c_str), "%04d-%02d-%02d %02d:%02d:%02d",
5569
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
56-
page += std::string(AUTOINDEX_FILENAME_MAXLEN - len, ' ');
57-
page += c_str;
70+
_ADD_TD_(page, c_str)
5871
// size
5972
if (item.type == 'd') {
6073
page += '-';
@@ -74,13 +87,17 @@ void make_index_of_page(const char* dir, std::string& page, const char* url) {
7487
hsize /= 1024.0f;
7588
snprintf(c_str, sizeof(c_str), "%.1fG", hsize);
7689
}
77-
page += c_str;
90+
_ADD_TD_(page, c_str)
7891
}
7992
}
80-
page += "\r\n";
93+
page += " </tr>\n";
8194
}
82-
page += R"(</pre>
95+
96+
#undef _ADD_TD_
97+
98+
page += R"( </table>
8399
<hr>
84100
</body>
85-
</html>)";
101+
</html>
102+
)";
86103
}

http/server/http_page.h

+19-7
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,25 @@ void make_http_status_page(http_status status_code, std::string& page);
2828
<body>
2929
<h1>Index of /downloads/</h1>
3030
<hr>
31-
<pre>
32-
<a href="../">../</a>
33-
<a href="docs/">docs/</a> 2019-08-23 15:27:48 -
34-
<a href="examples/">examples/</a> 2019-08-23 15:27:52 -
35-
<a href="README.txt">README.txt</a> 2019-08-23 19:15:42 0
36-
<a href="release/">release/</a> 2019-08-23 15:28:52 -
37-
</pre>
31+
<table border="0">
32+
<tr>
33+
<th align="left" width="30%">Name</th>
34+
<th align="left" width="20%">Date</th>
35+
<th align="left" width="20%">Size</th>
36+
</tr>
37+
<tr>
38+
<td><a href="../">../</a></td>
39+
</tr>
40+
<tr>
41+
<td><a href="libhv-vs-nginx.png">libhv-vs-nginx.png</a></td>
42+
<td>2021-03-10 12:33:57</td>
43+
<td>211.4K</td>
44+
</tr>
45+
<td><a href="中文.html">中文.html</a></td>
46+
<td>2022-04-25 15:37:12</td>
47+
<td>191</td>
48+
</tr>
49+
</table>
3850
<hr>
3951
</body>
4052
</html>

0 commit comments

Comments
 (0)