From 4c540e0d15436739f6d3613a80d6bbb95a619e25 Mon Sep 17 00:00:00 2001 From: Rajkumar Date: Sat, 27 May 2023 01:33:53 +0530 Subject: [PATCH] errors in migrating code to different files --- example/demo.f90 | 5 --- example/simple_get.f90 | 11 +++++ fpm.toml | 4 +- src/http-client.f90 | 10 ----- src/http.f90 | 56 +++++++++++++++++++++++++ src/http_client.f90 | 94 ++++++++++++++++++++++++++++++++++++++++++ src/http_request.f90 | 12 ++++++ src/http_response.f90 | 14 +++++++ 8 files changed, 190 insertions(+), 16 deletions(-) delete mode 100644 example/demo.f90 create mode 100644 example/simple_get.f90 delete mode 100644 src/http-client.f90 create mode 100644 src/http.f90 create mode 100644 src/http_client.f90 create mode 100644 src/http_request.f90 create mode 100644 src/http_response.f90 diff --git a/example/demo.f90 b/example/demo.f90 deleted file mode 100644 index 8f78bf8..0000000 --- a/example/demo.f90 +++ /dev/null @@ -1,5 +0,0 @@ -program demo -implicit none - -print *, "Put some examples in here!" -end program demo diff --git a/example/simple_get.f90 b/example/simple_get.f90 new file mode 100644 index 0000000..12554f6 --- /dev/null +++ b/example/simple_get.f90 @@ -0,0 +1,11 @@ +program simple_get + use http_client, only : response_type, http_request, HTTP_GET + implicit none + type(response_type) :: response + + response = http_request(url='https://jsonplaceholder.typicode.com/todos/1', method=HTTP_GET) + print *, "Response Code : ", response%status_code + print *, "Response Length : ", response%content_length + print *, "Response Content : ", response%content + +end program simple_get diff --git a/fpm.toml b/fpm.toml index 7e71ec7..f0cc6fc 100644 --- a/fpm.toml +++ b/fpm.toml @@ -1,4 +1,4 @@ -name = "http-client" +name = "http" version = "0.1.0" license = "MIT" author = "Fortran-lang" @@ -18,3 +18,5 @@ implicit-typing = false implicit-external = false source-form = "free" +[dependencies] +fortran-curl = {git = "https://github.com/interkosmos/fortran-curl.git"} \ No newline at end of file diff --git a/src/http-client.f90 b/src/http-client.f90 deleted file mode 100644 index 91e0c12..0000000 --- a/src/http-client.f90 +++ /dev/null @@ -1,10 +0,0 @@ -module http_client - implicit none - private - - public :: say_hello -contains - subroutine say_hello - print *, "Hello, http-client!" - end subroutine say_hello -end module http_client diff --git a/src/http.f90 b/src/http.f90 new file mode 100644 index 0000000..66187aa --- /dev/null +++ b/src/http.f90 @@ -0,0 +1,56 @@ +module http + use http_request + use http_response, only : response_type + use http_client + implicit none + + ! HTTP methods: + integer, parameter, public :: HTTP_GET = 1 + integer, parameter, public :: HTTP_HEAD = 2 + integer, parameter, public :: HTTP_POST = 3 + integer, parameter, public :: HTTP_PUT = 4 + integer, parameter, public :: HTTP_DELETE = 5 + integer, parameter, public :: HTTP_PATCH = 6 + + interface http_request + module procedure new_request + end interface http_request + + ! Procedure defination + public :: http_request + +contains + + ! Constructor for request_type type. + function new_request(url, method) result(response) + character(len=*) :: url + integer, optional :: method + type(request_type) :: request + type(response_type) :: response + type(client_type) :: client + + if(present(method)) then + if(method == 1) then + request%method = 'GET' + else if (method == 2) then + request%method = 'HEAD' + else if (method == 3) then + request%method = 'POST' + else if (method == 4) then + request%method = 'PUT' + else if(method == 5) then + request%method = 'DELETE' + else if( method == 6) then + request%method = 'PATCH' + end if + else + request%method = 'GET' + end if + request%url = url + client = client_type(request=request) + response = client%client_get_response() + + end function new_request + + +end module http \ No newline at end of file diff --git a/src/http_client.f90 b/src/http_client.f90 new file mode 100644 index 0000000..72f6e63 --- /dev/null +++ b/src/http_client.f90 @@ -0,0 +1,94 @@ +module http_client + use, intrinsic :: iso_c_binding + use, intrinsic :: iso_fortran_env, only: i4 => int32, i8 => int64, r4 => real32, r8 => real64 + use curl + use request_type + use response_type + implicit none + + ! http_client Type + type :: client_type + type(request_type) :: request + contains + procedure :: client_get_response + end type client_type + + interface client_type + module procedure new_client + end interface client_type + +contains + ! Constructor for client_type type. + function new_client(request) result(client) + type(client_type) :: client + type(request_type) :: request + + client%request = request + end function new_client + + function client_get_response(this) result(response) + class(client_type) :: this + type(response_type), target :: response + type(c_ptr) :: curl_ptr + integer :: rc + ! logic for populating response using fortran-curl + response%url = this%request%url + response%method = this%request%method + + curl_ptr = curl_easy_init() + + if (.not. c_associated(curl_ptr)) then + stop 'Error: curl_easy_init() failed' + end if + ! setting request URL + rc = curl_easy_setopt(curl_ptr, CURLOPT_URL, this%request%url // c_null_char) + ! setting request method + rc = curl_easy_setopt(curl_ptr, CURLOPT_CUSTOMREQUEST, this%request%method // c_null_char) + ! setting callback for writing received data + rc = curl_easy_setopt(curl_ptr, CURLOPT_WRITEFUNCTION, c_funloc(client_response_callback)) + ! setting response pointer to write callback + rc = curl_easy_setopt(curl_ptr, CURLOPT_WRITEDATA, c_loc(response)) + + ! Send request. + rc = curl_easy_perform(curl_ptr) + + if (rc /= CURLE_OK) then + print '(a)', 'Error: curl_easy_perform() failed' + stop + end if + ! setting response status_code + rc = curl_easy_getinfo(curl_ptr, CURLINFO_RESPONSE_CODE, response%status_code) + call curl_easy_cleanup(curl_ptr) + + end function client_get_response + + function client_response_callback(ptr, size, nmemb, client_data) bind(c) + type(c_ptr), intent(in), value :: ptr + integer(kind=c_size_t), intent(in), value :: size + integer(kind=c_size_t), intent(in), value :: nmemb + type(c_ptr), intent(in), value :: client_data + integer(kind=c_size_t) :: client_response_callback + type(response_type), pointer :: response + character(len=:), allocatable :: buf + + client_response_callback = int(0, kind=c_size_t) + + ! Are the passed C pointers associated? + if (.not. c_associated(ptr)) return + if (.not. c_associated(client_data)) return + + ! Convert C pointer to Fortran pointer. + call c_f_pointer(client_data, response) + if (.not. allocated(response%content)) response%content = '' + + ! Convert C pointer to Fortran allocatable character. + call c_f_str_ptr(ptr, buf, nmemb) + if (.not. allocated(buf)) return + response%content = response%content // buf + deallocate (buf) + response%content_length = response%content_length + nmemb + ! Return number of received bytes. + client_response_callback = nmemb + end function client_response_callback + +end module http_client \ No newline at end of file diff --git a/src/http_request.f90 b/src/http_request.f90 new file mode 100644 index 0000000..4588534 --- /dev/null +++ b/src/http_request.f90 @@ -0,0 +1,12 @@ +module http_request + use http_response, only : response_type + use http_client, only : client_type + implicit none + + ! Request Type + type, public :: request_type + character(len=:), public, allocatable :: url + character(len=:), public, allocatable :: method + end type request_type + +end module http_request \ No newline at end of file diff --git a/src/http_response.f90 b/src/http_response.f90 new file mode 100644 index 0000000..f3307c5 --- /dev/null +++ b/src/http_response.f90 @@ -0,0 +1,14 @@ +module http_response + use, intrinsic :: iso_c_binding, only : c_size_t + implicit none + + ! Response Type + type, public :: response_type + character(len=:), public, allocatable :: content + character(len=:), public, allocatable :: url + character(len=:), public, allocatable :: method + integer, public :: status_code + integer(kind=c_size_t), public:: content_length = 0 + end type response_type + +end module http_response \ No newline at end of file