FlightGear next
NasalHTTP.cxx
Go to the documentation of this file.
1// Expose HTTP module to Nasal
2//
3// Copyright (C) 2013 Thomas Geymayer
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License as
7// published by the Free Software Foundation; either version 2 of the
8// License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful, but
11// WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13// General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include "NasalHTTP.hxx"
24#include <Main/globals.hxx>
26
27#include <simgear/io/HTTPFileRequest.hxx>
28#include <simgear/io/HTTPMemoryRequest.hxx>
29
30#include <simgear/nasal/cppbind/from_nasal.hxx>
31#include <simgear/nasal/cppbind/to_nasal.hxx>
32#include <simgear/nasal/cppbind/NasalHash.hxx>
33#include <simgear/nasal/cppbind/Ghost.hxx>
34
35typedef nasal::Ghost<simgear::HTTP::Request_ptr> NasalRequest;
36typedef nasal::Ghost<simgear::HTTP::FileRequestRef> NasalFileRequest;
37typedef nasal::Ghost<simgear::HTTP::MemoryRequestRef> NasalMemoryRequest;
38
39FGHTTPClient& requireHTTPClient(const nasal::ContextWrapper& ctx)
40{
41 auto http = globals->get_subsystem<FGHTTPClient>();
42 if( !http )
43 ctx.runtimeError("Failed to get HTTP subsystem");
44
45 return *http;
46}
47
51static naRef f_http_save(const nasal::CallContext& ctx)
52{
53 const std::string url = ctx.requireArg<std::string>(0);
54
55 // Check for write access to target file
56 const std::string filename = ctx.requireArg<std::string>(1);
57 const SGPath validated_path = SGPath(filename).validate(true);
58
59 if( validated_path.isNull() )
60 ctx.runtimeError("Access denied: can not write to %s", filename.c_str());
61
62 return ctx.to_nasal
63 (
64 requireHTTPClient(ctx).client()->save(url, validated_path.utf8Str())
65 );
66}
67
71static naRef f_http_load(const nasal::CallContext& ctx)
72{
73 const std::string url = ctx.requireArg<std::string>(0);
74 return ctx.to_nasal( requireHTTPClient(ctx).client()->load(url) );
75}
76
77static naRef f_request_abort( simgear::HTTP::Request&,
78 const nasal::CallContext& ctx )
79{
80 // we need a request_ptr for cancel, not a reference. So extract
81 // the me object from the context directly.
82 simgear::HTTP::Request_ptr req = ctx.from_nasal<simgear::HTTP::Request_ptr>(ctx.me);
83 requireHTTPClient(ctx).client()->cancelRequest(req);
84 return naNil();
85}
86
87//------------------------------------------------------------------------------
88naRef initNasalHTTP(naRef globals, naContext c)
89{
90 using simgear::HTTP::Request;
91 typedef Request* (Request::*HTTPCallback)(const Request::Callback&);
92 NasalRequest::init("http.Request")
93 .member("url", &Request::url)
94 .member("method", &Request::method)
95 .member("scheme", &Request::scheme)
96 .member("path", &Request::path)
97 .member("host", &Request::host)
98 .member("port", &Request::port)
99 .member("query", &Request::query)
100 .member("status", &Request::responseCode)
101 .member("reason", &Request::responseReason)
102 .member("readyState", &Request::readyState)
103 .method("abort", f_request_abort)
104 .method("done", static_cast<HTTPCallback>(&Request::done))
105 .method("fail", static_cast<HTTPCallback>(&Request::fail))
106 .method("always", static_cast<HTTPCallback>(&Request::always));
107
108 using simgear::HTTP::FileRequest;
109 NasalFileRequest::init("http.FileRequest")
110 .bases<NasalRequest>();
111
112 using simgear::HTTP::MemoryRequest;
113 NasalMemoryRequest::init("http.MemoryRequest")
114 .bases<NasalRequest>()
115 .member("response", &MemoryRequest::responseBody);
116
117 nasal::Hash globals_module(globals, c),
118 http = globals_module.createHash("http");
119
120 http.set("save", f_http_save);
121 http.set("load", f_http_load);
122
123 return naNil();
124}
nasal::Ghost< simgear::HTTP::FileRequestRef > NasalFileRequest
Definition NasalHTTP.cxx:36
FGHTTPClient & requireHTTPClient(const nasal::ContextWrapper &ctx)
Definition NasalHTTP.cxx:39
nasal::Ghost< simgear::HTTP::Request_ptr > NasalRequest
Definition NasalHTTP.cxx:35
nasal::Ghost< simgear::HTTP::MemoryRequestRef > NasalMemoryRequest
Definition NasalHTTP.cxx:37
static naRef f_http_load(const nasal::CallContext &ctx)
http.load(url)
Definition NasalHTTP.cxx:71
static naRef f_request_abort(simgear::HTTP::Request &, const nasal::CallContext &ctx)
Definition NasalHTTP.cxx:77
naRef initNasalHTTP(naRef globals, naContext c)
Definition NasalHTTP.cxx:88
static naRef f_http_save(const nasal::CallContext &ctx)
http.save(url, filename)
Definition NasalHTTP.cxx:51
simgear::HTTP::Client * client()
FGGlobals * globals
Definition globals.cxx:142