Skip to content

errors in migrating code to different files #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions example/demo.f90

This file was deleted.

11 changes: 11 additions & 0 deletions example/simple_get.f90
Original file line number Diff line number Diff line change
@@ -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
4 changes: 3 additions & 1 deletion fpm.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name = "http-client"
name = "http"
version = "0.1.0"
license = "MIT"
author = "Fortran-lang"
Expand All @@ -18,3 +18,5 @@ implicit-typing = false
implicit-external = false
source-form = "free"

[dependencies]
fortran-curl = {git = "https://github.com/interkosmos/fortran-curl.git"}
10 changes: 0 additions & 10 deletions src/http-client.f90

This file was deleted.

56 changes: 56 additions & 0 deletions src/http.f90
Original file line number Diff line number Diff line change
@@ -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
94 changes: 94 additions & 0 deletions src/http_client.f90
Original file line number Diff line number Diff line change
@@ -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
12 changes: 12 additions & 0 deletions src/http_request.f90
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions src/http_response.f90
Original file line number Diff line number Diff line change
@@ -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