| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- #pragma once
- #include "common.h"
- #include "obj.h"
- #include "vm.h"
- #include "_generated.h"
- #if __has_include("httplib.h")
- #include "httplib.h"
- namespace pkpy {
- inline void add_module_requests(VM* vm){
- static StrName m_requests("requests");
- static StrName m_Response("Response");
- PyObject* mod = vm->new_module(m_requests);
- CodeObject_ code = vm->compile(kPythonLibs["requests"], "requests.py", EXEC_MODE);
- vm->_exec(code, mod);
- vm->bind_func<4>(mod, "_request", [](VM* vm, ArgsView args){
- Str method = CAST(Str&, args[0]);
- Str url = CAST(Str&, args[1]);
- PyObject* headers = args[2]; // a dict object
- PyObject* body = args[3]; // a bytes object
- if(url.index("http://") != 0){
- vm->ValueError("url must start with http://");
- }
- for(char c: url){
- switch(c){
- case '.':
- case '-':
- case '_':
- case '~':
- case ':':
- case '/':
- break;
- default:
- if(!isalnum(c)){
- vm->ValueError(fmt("invalid character in url: '", c, "'"));
- }
- }
- }
- int slash = url.index("/", 7);
- Str path = "/";
- if(slash != -1){
- path = url.substr(slash);
- url = url.substr(0, slash);
- if(path.empty()) path = "/";
- }
- httplib::Client client(url.str());
- httplib::Headers h;
- if(headers != vm->None){
- List list = CAST(List&, headers);
- for(auto& item : list){
- Tuple t = CAST(Tuple&, item);
- Str key = CAST(Str&, t[0]);
- Str value = CAST(Str&, t[1]);
- h.emplace(key.str(), value.str());
- }
- }
- auto _to_resp = [=](const httplib::Result& res){
- return vm->call(
- vm->_modules[m_requests]->attr(m_Response),
- VAR(res->status),
- VAR(res->reason),
- VAR(Bytes(res->body))
- );
- };
- if(method == "GET"){
- httplib::Result res = client.Get(path.str(), h);
- return _to_resp(res);
- }else if(method == "POST"){
- Bytes b = CAST(Bytes&, body);
- httplib::Result res = client.Post(path.str(), h, b.data(), b.size(), "application/octet-stream");
- return _to_resp(res);
- }else if(method == "PUT"){
- Bytes b = CAST(Bytes&, body);
- httplib::Result res = client.Put(path.str(), h, b.data(), b.size(), "application/octet-stream");
- return _to_resp(res);
- }else if(method == "DELETE"){
- httplib::Result res = client.Delete(path.str(), h);
- return _to_resp(res);
- }else{
- vm->ValueError("invalid method");
- }
- UNREACHABLE();
- });
- }
- } // namespace pkpy
- #else
- inline void add_module_requests(void* vm){ }
- #endif
|