Skip to content
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

Bundle for making HTTP GETrequests #369

Merged
merged 13 commits into from
Apr 20, 2016

Conversation

pengstrom
Copy link
Contributor

There were no Encore bindings to the C functions for network programming. I have written a convenient wrapper around some C code for making http requests able to receive an arbitrary sized response.

Testing is a little weird since we don't have a development web server of our own. Instead, I request www.httpbin.org to test different return codes.

To make a request, import Request and use the GET function to make a request

let r = new Request();
let res = get r.GET("www.httpbin.org", 80, "/ip");
print("Response is:\n{}\n", res.raw);

I have only implemented the GET functionality, and the response object only contains the raw request. I plan on enabling more methods and convenient getters in the response object.

Using network programming in C, we wrap the functionality in an active
Encore class.
A rudimetary class Response with a single field for the raw respose is
used as the resturn type of Response.GET

Using the website 'www.httpbin.org' we test responses of statuses 200,
300, 400 and 500.

// Allocate the buffer and result
int result_size = buffer_size + 1;
char *buffer = malloc(buffer_size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be allocated on the stack? Now it looks like this memory will leak!

@EliasC
Copy link
Contributor

EliasC commented Apr 11, 2016

@pengstrom: See #373 for methods that might be useful for your tests!

print "/status/".concatenate(string_from_int(42));

@kikofernandez
Copy link
Contributor

As a side note, the PonyRT has support for Async IO. I read an article where someone mentioned that it is pretty good (I cannot find the article now...)
In any case, I cannot wait to start creating my own server! :)

@pengstrom
Copy link
Contributor Author

I've updated my branch with your kind suggestions.

I'm now using the native conversion functions for strings, and the memory is (hopefully) garbage collected.

In addition, a function encore_realloc(pony_ctx_t *ctx, void* p, size_t s) (a wrapper around pony_realloc) was written for dynamic resizing. I'd like some ideas how this could be zeroed, since arithmetic on void pointers is not allowed.

#include <netinet/in.h> /* struct sockaddr_in, struct sockaddr */
#include <netdb.h> /* struct hostent, gethostbyname */

#include <encore.h> /* encore_alloc, encore_realloc */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file compiles for me even if I remove stdio.h, stdlib.h, string.h and encore.h.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's included elsewhere up the chain. But isn't it good to be explicit about dependencies?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't hurt having them there I guess. At least encore.h seems redundant though, as it must be present for the Encore code to compile. I have no strong feelings about removing or keeping them.

@EliasC
Copy link
Contributor

EliasC commented Apr 17, 2016

Only minor things left, then I think this is mergable!

Also used native string functions for concatenating stings.
@EliasC
Copy link
Contributor

EliasC commented Apr 17, 2016

I'm in favour of merging this now! Will do so tomorrow if no one objects.

@albertnetymk
Copy link
Contributor

I don't think it's needed for the identical comment to appear in both header and source file.

There are trailing space in bundles/prototype/Request/Request.enc.

For the embedded C code, clang -Weverything gives a few warnings; the ones with noreturn, losing precision on ssize_t to int should be addressed, IMO.

getRequest's naming seems odd, for it returns response, not request. Maybe I misunderstood sth.

It's unclear to me why strcpy is needed in GET of Request.

I didn't get any error on running RequestTest. @EliasC Are you referring to this PR with the crashing you mentioned on slack?

@EliasC
Copy link
Contributor

EliasC commented Apr 18, 2016

@albertnetymk: I'm getting errors if I increase the number of iterations in main. Some of the errors is fixed by #384, but I'm still seeing GC crashes (which go away with --ponythreads 1).

@albertnetymk
Copy link
Contributor

@EliasC I can't reproduce the failure with repeat i <- 100 around the original code. What code did you use to see the crash?

@EliasC
Copy link
Contributor

EliasC commented Apr 18, 2016

@albertnetymk: I see the crash with for n in [200..500 by 10].

@albertnetymk
Copy link
Contributor

@EliasC I can confirm it on my box. Looks like a data-race caused bug from the error msg in gdb.

@EliasC
Copy link
Contributor

EliasC commented Apr 18, 2016

@albertnetymk: 👍

Also, it goes away with --ponythreads 1.

@albertnetymk
Copy link
Contributor

The crashing is concluded to be caused by misusing obsolete ctx after work stealing. The PR is not to be blamed for the crashing.

@pengstrom
Copy link
Contributor Author

Thanks for your feedback!

@albertnetymk

For the embedded C code, clang -Weverything gives a few warnings; the ones with noreturn, losing precision on ssize_t to int should be addressed, IMO.

I'm only losing precision with the functions write and read which are limited to 4096 bytes. So if I'm not mistaken, it should not be an issue.

For the noreturn, is it enough if I add the attribute to the error function, or should I write it in another way?

The comment is kept in the header
@albertnetymk
Copy link
Contributor

So if I'm not mistaken, it should not be an issue.

True, but it would be surprising to see that the program starts to behave strangely with a larger buffer size. The benefit of using a macro for buffer size is that the rest of the program can be kept intact.

For the noreturn, is it enough if I add the attribute to the error function

Think so.

@pengstrom
Copy link
Contributor Author

@albertnetymk
You're right. I'll make the function use ssize_t throughout.

@albertnetymk
Copy link
Contributor

Looks good.
Two very minor comments:

  • indentation is inconsistent 2 spaces vs 4 spaces
  • exceeding 80 columns

Can be merged as it is. I would suggest to squash it into one commit on merging, unless the author of this PR plans to do a rebase to tidy the history a bit.

@pengstrom
Copy link
Contributor Author

Go ahead and squash!

@albertnetymk albertnetymk merged commit a95128e into parapluu:development Apr 20, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants