FastAPI

1
2
pip3 install fastapi
pip3 install uvicorn

DEMO

  • main.py
1
2
3
4
5
6
7
8
9
10
11
from fastapi import FastAPI

app = FastAPI()

@app.get('/')
def read_root():
return {'Hello': 'World'}

@app.get('/ftp/{file}')
def read(file: str):
return {'content': open(file, 'r').read()}
  • 启动API
1
uvicorn main:app --reload
  • API文档自动生成在:http://127.0.0.1:8000/docs

简单调用

1
2
3
import requests
requests.get('http://127.0.0.1:8000/').text # {"Hello":"World"}
requests.get('http://127.0.0.1:8000/ftp/1.txt').text # {"content":"1.txt content"}

C语言调用

  • (这个真的写的我人都死过去了。。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include     "string.h"
#include "arpa/inet.h"
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/socket.h"

typedef struct headers{
char *method, *path, *url;
char *ua, *ac, *ace;
int _method_len, _total_method_len;
int _path_len, _total_path_len;
int _url_len, _total_url_len;
int port;
}headers;

static void package_append_char(headers*p, int mpu, char c){
if(mpu == 0){
if(p->_method_len == p->_total_method_len)p->method = (char*)realloc(p->method, p->_total_method_len + 10);
*(p->method + p->_method_len++) = c;
*(p->method + p->_method_len) = 0;
} else if(mpu == 1) {
if(p->_path_len == p->_total_path_len)p->path = (char*)realloc(p->path, p->_total_path_len + 100);
*(p->path + p->_path_len++) = c;
*(p->path + p->_path_len) = 0;
} else if(mpu == 2) {
if(p->_url_len == p->_total_url_len)p->url = (char*)realloc(p->url, p->_total_url_len + 100);
*(p->url + p->_url_len++) = c;
*(p->url + p->_url_len) = 0;
}
}

headers new_headers(){
headers res;
memset(&res, 0, sizeof(res));
res.method = (char*)malloc(10);
res.path = (char*)malloc(500);
res.url = (char*)malloc(500);
res._total_method_len = 10;
res._total_path_len = res._total_url_len = 500;
res.method[0] = res.path[0] = res.url[0] = 0;
res.port = 80;
res.ua = "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15";
res.ac = "Accept: application/json, text/javascript, */*; q=0.01";
res.ace = "Accept-Encoding: gzip, deflate, br";
return res;
}

void del_headers(headers p){
free(p.method);
free(p.path);
free(p.url);
}

int startswith(char*str1, char*str2){
while(*str1 && *str2){
if(*str1 != *str2)return 0;
++str1;
++str2;
}
if(!*str1 || *str2)return 0;
return 1;
}

headers format_url(char*url){
char*cur;
headers res = new_headers();
if(startswith(url, "https://"))
for(cur=url+8;*cur;++cur){
if(*cur!=':' && *cur!='/')package_append_char(&res, 2, *cur);
else break;
}
else if(startswith(url, "http://"))
for(cur=url+7;*cur;++cur){
if(*cur!=':' && *cur!='/')package_append_char(&res, 2, *cur);
else break;
}
else for(cur=url;*cur;++cur){
if(*cur!=':' && *cur!='/')package_append_char(&res, 2, *cur);
else break;
}
if(*cur == ':'){
++cur;
res.port = 0;
while(*cur && *cur!='/')res.port = res.port * 10 + (*cur++ - '0');
}
if(*cur == '/')while(*cur)package_append_char(&res, 1, *cur++);
else package_append_char(&res, 1, '/');
cur = "GET";
while(*cur)package_append_char(&res, 0, *cur++);
return res;
}

void call_api(headers head, char*res){
int sc = socket(AF_INET, SOCK_STREAM, 0);
if(sc < 0){
perror("Create socket failed\n");
return;
}
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(head.port);
inet_pton(AF_INET, head.url, &serveraddr.sin_addr.s_addr);
if(connect(sc, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0){
perror("Connect failed\n");
return;
}
char msg[2048];
snprintf(msg, 2047, "%s %s HTTP/1.1\r\n%s\r\n%s\r\n%s\r\n\r\n", head.method, head.path, head.ac, head.ace, head.ua);
int msg_len = strlen(msg);
if(write(sc, msg, msg_len) != msg_len){
perror("POST ERROR");
return;
}
size_t sz;
memset(msg, 0, sizeof(msg));
if ( (sz = read( sc, msg, sizeof(msg) ) ) < 0 ){
puts("read failed");
return;
}
close(sc);
strcpy(res, msg);
}

int main(int argc, char**argv){
if(argc<2){
printf("Usage: %s url", argv[0]);
return -1;
}
headers head = format_url(argv[1]);
char* res = (char*)malloc(2048);
call_api(head, res);
del_headers(head);
printf("%.*s\n", 290, res);
free(res);
return 0;
}

利用Qpro编译运行

1
2
qrun -b                    # 编译
qrun http://127.0.0.1:8000 # 运行

也可以这样:

1
qrun -br http://127.0.0.1:8000 # 编译且运行

也可以直接编译运行

1
2
gcc -std=c11 main.c -O3 -o main # 编译
./main http://127.0.0.1:8000 # 运行