{"id":13401520,"url":"https://github.com/renatoathaydes/rawhttp","last_synced_at":"2025-04-06T07:15:43.563Z","repository":{"id":27911803,"uuid":"112115759","full_name":"renatoathaydes/rawhttp","owner":"renatoathaydes","description":"HTTP library to make it easy to deal with raw HTTP.","archived":false,"fork":false,"pushed_at":"2023-08-26T17:33:21.000Z","size":3960,"stargazers_count":201,"open_issues_count":2,"forks_count":29,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-10-30T04:55:16.487Z","etag":null,"topics":["http","http-client","http-server","java-library","networking"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/renatoathaydes.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-26T20:52:33.000Z","updated_at":"2024-10-14T10:00:04.000Z","dependencies_parsed_at":"2024-10-25T22:26:38.903Z","dependency_job_id":"b5726bba-18a5-4f75-af83-ad14374a04b6","html_url":"https://github.com/renatoathaydes/rawhttp","commit_stats":null,"previous_names":[],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Frawhttp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Frawhttp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Frawhttp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Frawhttp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/renatoathaydes","download_url":"https://codeload.github.com/renatoathaydes/rawhttp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247445682,"owners_count":20939961,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http","http-client","http-server","java-library","networking"],"created_at":"2024-07-30T19:01:03.693Z","updated_at":"2025-04-06T07:15:43.545Z","avatar_url":"https://github.com/renatoathaydes.png","language":"Java","funding_links":[],"categories":["Java","网络编程","开发工具\u0026框架"],"sub_categories":[],"readme":"# RawHTTP\n\n| Module Name         |                                                                                                      Latest Version                                                                                                      | Documentation                                                                                               | Javadocs                                                                                                                                                      |\n|---------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|-------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| rawhttp-core        |           [![rawhttp-core](https://img.shields.io/maven-central/v/com.athaydes.rawhttp/rawhttp-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:com.athaydes.rawhttp%20%20a:rawhttp-core)            | [RawHTTP Core](https://renatoathaydes.github.io/rawhttp/docs/index.html)                                    | [![javadoc](https://javadoc.io/badge2/com.athaydes.rawhttp/rawhttp-core/javadoc.svg)](https://javadoc.io/doc/com.athaydes.rawhttp/rawhttp-core)               |\n| rawhttp-cli         |             [![rawhttp-cli](https://img.shields.io/maven-central/v/com.athaydes.rawhttp/rawhttp-cli.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:com.athaydes.rawhttp%20%20a:rawhttp-cli)             | [RawHTTP CLI](https://renatoathaydes.github.io/rawhttp/rawhttp-modules/cli.html)                            | [![javadoc](https://javadoc.io/badge2/com.athaydes.rawhttp/rawhttp-cli/javadoc.svg)](https://javadoc.io/doc/com.athaydes.rawhttp/rawhttp-cli)                 |\n| rawhttp-duplex      |        [![rawhttp-duplex](https://img.shields.io/maven-central/v/com.athaydes.rawhttp/rawhttp-duplex.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:com.athaydes.rawhttp%20%20a:rawhttp-duplex)         | [RawHTTP Duplex](https://renatoathaydes.github.io/rawhttp/rawhttp-modules/duplex.html)                      | [![javadoc](https://javadoc.io/badge2/com.athaydes.rawhttp/rawhttp-duplex/javadoc.svg)](https://javadoc.io/doc/com.athaydes.rawhttp/rawhttp-duplex)           |\n| rawhttp-cookies     |       [![rawhttp-cookies](https://img.shields.io/maven-central/v/com.athaydes.rawhttp/rawhttp-cookies.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:com.athaydes.rawhttp%20%20a:rawhttp-cookies)       | [RawHTTP Cookies](https://renatoathaydes.github.io/rawhttp/rawhttp-modules/cookies.html)                    | [![javadoc](https://javadoc.io/badge2/com.athaydes.rawhttp/rawhttp-cookies/javadoc.svg)](https://javadoc.io/doc/com.athaydes.rawhttp/rawhttp-cookies)         |\n| rawhttp-req-in-edit | [![rawhttp-req-in-edit](https://img.shields.io/maven-central/v/com.athaydes.rawhttp/rawhttp-req-in-edit.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:com.athaydes.rawhttp%20%20a:rawhttp-req-in-edit) | [RawHTTP ReqInEdit (HTTP Tests)](https://renatoathaydes.github.io/rawhttp/rawhttp-modules/req-in-edit.html) | [![javadoc](https://javadoc.io/badge2/com.athaydes.rawhttp/rawhttp-req-in-edit/javadoc.svg)](https://javadoc.io/doc/com.athaydes.rawhttp/rawhttp-req-in-edit) |\n\n[![Actions Status](https://github.com/renatoathaydes/rawhttp/workflows/Build%20And%20Test%20on%20All%20OSs/badge.svg)](https://github.com/renatoathaydes/rawhttp/actions)\n\nA Java library to make it easy to deal with raw HTTP 1.1, as defined by [RFC-7230](https://tools.ietf.org/html/rfc7230),\nand most of HTTP 1.0 ([RFC-1945](https://tools.ietf.org/html/rfc1945)).\n\n\u003e For details about using RawHTTP and the motivation for this project, see the\n [blog post](https://sites.google.com/a/athaydes.com/renato-athaydes/posts/announcingrawhttp-ajvmlibraryforhandlingrawhttp)\n I wrote about it!\n\n\u003e For testing HTTP servers, check out the [blog post I wrote about rawhttp-req-in-edit](https://renato.athaydes.com/posts/writing-http-files-for-testing.html),\n\u003e which lets you write [HTTP files](https://www.jetbrains.com/help/idea/exploring-http-syntax.html) to send requests \n\u003e and assert responses using JS scripts. \n\n🌎 For more documentation, [visit the website](https://renatoathaydes.github.io/rawhttp).\n\n## Introduction\n\nHTTP is really simple in 99.9% of cases.\n\nFor example, the raw HTTP request you would make to fetch a resource from a web server looks like this:\n\n\u003e The example below is taken from the [HTTP 1.1 RFC 7230](https://tools.ietf.org/html/rfc7230#section-2.1).\n\n```\nGET /hello.txt HTTP/1.1\nUser-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3\nHost: www.example.com\nAccept-Language: en, mi\n```\n\nTo send that request out to a HTTP server using RawHTTP, you can parse the Request and stream it out via a \n`Socket`.\n\nHere's the whole code to do that:\n\n```java\nRawHttp rawHttp = new RawHttp();\n\nRawHttpRequest request = rawHttp.parseRequest(\n    \"GET /hello.txt HTTP/1.1\\r\\n\" +\n    \"User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3\\r\\n\" +\n    \"Host: www.example.com\\r\\n\" +\n    \"Accept-Language: en, mi\");\nSocket socket = new Socket(\"www.example.com\", 80);\nrequest.writeTo(socket.getOutputStream());\n```\n\nTo read the response, it's just as easy:\n\n```java\nRawHttpResponse\u003c?\u003e response = rawHttp.parseResponse(socket.getInputStream());\n\n// call \"eagerly()\" in order to download the body\nSystem.out.println(response.eagerly());\n```\n\nWhich prints the complete response:\n\n```\nHTTP/1.1 404 Not Found\nAccept-Ranges: bytes\nCache-Control: max-age=604800\nContent-Type: text/html\nDate: Mon, 04 Dec 2017 21:19:04 GMT\nExpires: Mon, 11 Dec 2017 21:19:04 GMT\nLast-Modified: Sat, 02 Dec 2017 02:10:22 GMT\nServer: ECS (lga/1389)\nVary: Accept-Encoding\nX-Cache: 404-HIT\nContent-Length: 1270\n\n\n\u003c!doctype html\u003e\n...\n```\n\nA `RawHttpResponse`, just like a `RawHttpRequest` can be written to a `File`'s, `ServerSocket`'s\nor any other `OutpuStream`:\n\n```java\ntry (OutputStream out = Files.newOutputStream(responseFile.toPath())) {\n    response.writeTo(out);\n}\n```\n\nThat simple!\n\nNotice that just with the above, you have everything you need to send and receive HTTP messages. \n\nTo illustrate that, here is a simple implementation of a HTTP server that waits for a single request,\nthen responds with a valid response:\n\n```java\nRawHttp http = new RawHttp();\nServerSocket server = new ServerSocket(8083);\n\nnew Thread(() -\u003e {\n    try {\n        Socket client = server.accept();\n        RawHttpRequest request = http.parseRequest(client.getInputStream());\n\n        if (request.getUri().getPath().equals(\"/saysomething\")) {\n            http.parseResponse(\"HTTP/1.1 200 OK\\n\" +\n                    \"Content-Type: text/plain\\n\" +\n                    \"Content-Length: 9\\n\" +\n                    \"\\n\" +\n                    \"something\").writeTo(client.getOutputStream());\n        } else {\n            http.parseResponse(\"HTTP/1.1 404 Not Found\\n\" +\n                    \"Content-Type: text/plain\\n\" +\n                    \"Content-Length: 0\\n\" +\n                    \"\\n\").writeTo(client.getOutputStream());\n        }\n    } catch (IOException e) {\n        e.printStackTrace();\n    }\n}).start();\n```\n\n## HTTP client\n\nEven though it's quite simple to implement your own HTTP client by using the `RawHttp` class to parse \nrequests and responses (which can then be transmitted via Sockets), RawHTTP offers a simple HTTP client definition\n(and implementation) that makes it a little bit more convenient to consume HTTP APIs.\n\nHere's the [`RawHttpClient`](rawhttp-core/src/main/java/rawhttp/core/client/RawHttpClient.java) interface:\n\n```java\npublic interface RawHttpClient\u003cResponse\u003e {\n    RawHttpResponse\u003cResponse\u003e send(RawHttpRequest request) throws IOException;\n}\n```   \n\nThe `Response` type parameter allows implementations to expose their own type for HTTP Responses, if needed.\n\nIn the core module, a simple implementation is provided: [`TcpRawHttpClient`](rawhttp-core/src/main/java/rawhttp/core/client/TcpRawHttpClient.java).\n\nExample usage:\n\n```java\nRawHttpClient\u003c?\u003e client = new TcpRawHttpClient();\nEagerHttpResponse\u003c?\u003e response = client.send(request).eagerly();\n```\n\n\u003e Unless you want to take care of streaming the response body later, always call `eagerly()`\n  as shown above to consume the full response body (allowing the connection to be re-used).\n\nOther implementations are available in separate modules:\n\n* `RawHttpComponentsClient` - based on HttpComponents's HttpClient.\n\n\u003e Requires the `rawhttp:rawhttp-httpcomponents` module.\n\nYou can use this if you need support for external specifications, such as\ncookies ([RFC-6265](https://tools.ietf.org/html/rfc6265)), or basic-auth, for example.\n\nExample usage:\n\n```java\n// use a default instance of CloseableHttpClient\nRawHttpClient\u003c?\u003e client = new RawHttpComponentsClient();\n\n// or create and configure your own client, then pass it into the constructor\nCloseableHttpClient httpClient = HttpClients.createDefault();\nRawHttpClient\u003c?\u003e client = new RawHttpComponentsClient(httpClient);\n```\n\n## HTTP server\n\nRawHTTP also contains a [package](rawhttp-core/src/main/java/rawhttp/core/server) defining a few types\nthat describe a simple HTTP server.\n\nThe main type is the interface `RawHttpServer`, which uses a `Router` to route HTTP requests, returning a HTTP response.\n`Router` is a functional interface (i.e. it can be implemented with a Java lambda), so implementing a full\nserver is very simple.\n\nA default implementation of `TcpRawHttpServer` is provided... it spans a `Thread` (but re-uses it when possible) for \neach connected client.\n\nHere's an example, written in Kotlin, of how to use `RawHttpServer`:\n\n```kotlin\nval server = TcpRawHttpServer(8093)\n\nserver.start { req -\u003e\n    when (req.uri.path) {\n        \"/hello\", \"/\" -\u003e\n            when (req.method) {\n                \"GET\" -\u003e\n                    http.parseResponse(\"HTTP/1.1 200 OK\\n\" +\n                            \"Content-Type: text/plain\"\n                    ).withBody(StringBody(\"Hello RawHTTP!\"))\n                else -\u003e\n                    http.parseResponse(\"HTTP/1.1 405 Method Not Allowed\\n\" +\n                            \"Content-Type: text/plain\"\n                    ).withBody(StringBody(\"Sorry, can't handle this method\"))\n            }\n        else -\u003e\n            http.parseResponse(\"HTTP/1.1 404 Not Found\\n\" +\n                    \"Content-Type: text/plain\"\n            ).withBody(StringBody(\"Content was not found\"))\n    }\n}\n```\n\n## Samples\n\nSeveral samples showing how to use RawHTTP, including all [examples](samples/src/test/java/rawhttp/samples/JavaSample.java)\nin this page, can be found in the [samples](samples) project.\n\n\u003e Note: to run the samples, execute the tests with the `-Prun-samples` argument.\n\nThe `rawhttp-duplex` module has its own sample, a [chat application](rawhttp-duplex/src/test/kotlin/chat-example.kt).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenatoathaydes%2Frawhttp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenatoathaydes%2Frawhttp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenatoathaydes%2Frawhttp/lists"}