Skip to content

Instantly share code, notes, and snippets.

@MagnificentPako
Last active April 23, 2020 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MagnificentPako/b67b081d5cac0d0185efd52c4a20a595 to your computer and use it in GitHub Desktop.
Save MagnificentPako/b67b081d5cac0d0185efd52c4a20a595 to your computer and use it in GitHub Desktop.
#!/usr/bin/env swipl
:- use_module(library(shell)).
:- use_module(library(option)).
:- use_module(library(crypto)).
:- use_module(library(random)).
:- use_module(library(http/http_host)).
:- use_module(library(http/http_error)).
:- use_module(library(http/html_write)).
:- use_module(library(http/http_files)).
:- use_module(library(http/http_client)).
:- use_module(library(http/http_header)).
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_parameters)).
:- use_module(library(http/http_unix_daemon)).
:- use_module(library(http/http_multipart_plugin)).
:- multifile prolog:message//1.
:- http_handler(root(.), home_page, []).
:- http_handler(root(.), main, [methods(get, post)]).
:- http_handler(root(u), file, [prefix]).
file(Request) :-
member(path(Path), Request),
sformat(Path_, ".~w", [Path]),
http_reply_file(Path_, [], Request).
home_page(_Request) :-
reply_html_page(
title('Upload a file'),
[ h1('Upload a file')
, form([ method('POST')
, action(location_by_id(main))
, enctype('multipart/form-data')
],
[ input([type(file), name(file)])
, input([type(submit), value('Upload!')])
])
]).
upload(Request) :-
http_read_data(Request, Parts, [ on_filename(save_file)]),
format('Content-type: text/plain~n~n'),
memberchk(file=file(FileName, Saved), Parts),
file_name_extension(_, Extension, FileName),
randseq(8, 255, Bytes),
hex_bytes(Hex, Bytes),
file_name_extension(Hex, Extension, FN),
working_directory(CWD, CWD),
sformat(NewFile, "~w/u/~w", [CWD, FN]),
rename_file(Saved, NewFile),
http_public_host_url(Request, Host),
format('~w/u/~w~n', [Host,FN]).
upload(_Request) :-
throw(http_reply(bad_request(bad_file_upload))).
main(Request) :-
multipart_post_request(Request),
!,
upload(Request).
main(_) :-
home_page(_).
save_file(In, file(FileName, File), Options) :-
option(filename(FileName), Options),
setup_call_cleanup(
tmp_file_stream(octet, File, Out),
copy_stream_data(In, Out),
close(Out)).
multipart_post_request(Request) :-
memberchk(method(post), Request),
memberchk(content_type(ContentType), Request),
http_parse_header_value(
content_type, ContentType,
media(multipart/'form-data', _)).
prolog:message(bad_file_upload) -->
[ 'A file upload must be submitted as multipart/form-data using', nl,
'name=file and providing a file-name'
].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment