{"id":24783376,"url":"https://github.com/chaunsin/go-har","last_synced_at":"2025-10-12T06:32:17.044Z","repository":{"id":216154307,"uuid":"740373423","full_name":"chaunsin/go-har","owner":"chaunsin","description":"golang parses http HAR files","archived":false,"fork":false,"pushed_at":"2025-01-14T07:44:28.000Z","size":130,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-14T08:42:00.556Z","etag":null,"topics":["fileparser","files","go","har","har-files","har-model","http"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chaunsin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2024-01-08T08:06:10.000Z","updated_at":"2025-01-14T07:44:31.000Z","dependencies_parsed_at":"2024-06-21T19:23:26.576Z","dependency_job_id":"15620e85-c1a0-4529-b45a-57f1e317f360","html_url":"https://github.com/chaunsin/go-har","commit_stats":null,"previous_names":["chaunsin/go-har"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaunsin%2Fgo-har","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaunsin%2Fgo-har/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaunsin%2Fgo-har/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chaunsin%2Fgo-har/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chaunsin","download_url":"https://codeload.github.com/chaunsin/go-har/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236176749,"owners_count":19107395,"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":["fileparser","files","go","har","har-files","har-model","http"],"created_at":"2025-01-29T12:16:46.548Z","updated_at":"2025-10-12T06:32:17.031Z","avatar_url":"https://github.com/chaunsin.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-har\n\n[![GoDoc](https://godoc.org/github.com/chaunsin/go-har?status.svg)](https://godoc.org/github.com/chaunsin/go-har) [![Go Report Card](https://goreportcard.com/badge/github.com/chaunsin/go-har)](https://goreportcard.com/report/github.com/chaunsin/go-har)\n\ngolang parsing and constructing HAR files\n\n## What is Har?\n\nhttps://w3c.github.io/web-performance/specs/HAR/Overview.html\n\nhttps://toolbox.googleapps.com/apps/har_analyzer/\n\n## Feature\n\n- supports standard HAR-1.2 content parsing\n- replay HTTP request based on har content stub content\n- supports HTTP synchronous requests and asynchronous concurrent requests\n- .har file import and export\n- can be embedded in HTTP services to present data\n- build HAR based on http.Request and http.Response\n\n## Use restriction\n\n- golang version \u003e= 1.23.0\n\n## Example\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n\t\"time\"\n\n\thar \"github.com/chaunsin/go-har\"\n)\n\nfunc Example() {\n\tvar path = \"./testdata/zh.wikipedia.org.har\"\n\t// parse har file\n\th, err := Parse(path, WithCookie(true))\n\tif err != nil {\n\t\tlog.Fatalf(\"Parse: %s\", err)\n\t}\n\thar := h.Export().Log\n\tfmt.Printf(\"version: %s create: %+v entries: %v\\n\", har.Version, har.Creator, h.EntryTotal())\n\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tdefer cancel()\n\n\t// construct request filter\n\tfilter := []RequestOption{\n\t\tWithRequestUrlIs(\"https://zh.wikipedia.org/wiki/.har\"),\n\t\tWithRequestMethod(\"GET\"),\n\t\t// add another filter\n\t}\n\n\t// concurrent execution http request\n\treceipt, err := h.SyncExecute(ctx, filter...)\n\tif err != nil {\n\t\tlog.Fatalf(\"SyncExecute: %s\", err)\n\t}\n\tfor r := range receipt {\n\t\tswitch {\n\t\tcase errors.Is(r.err, context.DeadlineExceeded):\n\t\t\tlog.Printf(\"%s request is timeout!\", r.Entry.Request.URL)\n\t\t\tcontinue\n\t\tcase r.err != nil:\n\t\t\tlog.Printf(\"%s request failed: %s\\n\", r.Entry.Request.URL, r.Error())\n\t\t\tcontinue\n\t\t}\n\n\t\t// Anonymous functions avoid body resource leakage\n\t\tfunc() {\n\t\t\tdefer r.Response.Body.Close()\n\t\t\t_, err := io.ReadAll(r.Response.Body)\n\t\t\tif err != nil {\n\t\t\t\tlog.Fatalf(\"readall err:%s\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tfmt.Printf(\"url: %s status: %s\\n\", r.Entry.Request.URL, r.Response.Status)\n\t\t}()\n\t}\n\n\t// add a new golang standard http request\n\tuniqueId := \"1\"\n\trequest, err := http.NewRequest(http.MethodGet, \"https://www.baidu.com\", nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tif err := h.AddRequest(uniqueId, request); err != nil {\n\t\t// err maybe unique id is repeated\n\t\tlog.Fatalf(\"add request failed: %s\", err)\n\t}\n\n\t// exclude other requests, ready for execution https://www.baidu.com\n\tfilter = []RequestOption{WithRequestUrlIs(\"https://www.baidu.com\")}\n\n\t// sequential execution http request\n\texecReceipt, err := h.Execute(context.TODO(), filter...)\n\tif err != nil {\n\t\tlog.Fatalf(\"Execute: %s\", err)\n\t}\n\tfor _, r := range execReceipt {\n\t\tif r.Error() != nil {\n\t\t\tlog.Printf(\"%s request failed: %s\\n\", r.Entry.Request.URL, r.Error())\n\t\t\tcontinue\n\t\t}\n\t\tfunc() {\n\t\t\tdefer r.Response.Body.Close()\n\t\t\t// read body do something's\n\t\t\t_, err := io.ReadAll(r.Response.Body)\n\t\t\tif err != nil {\n\t\t\t\tlog.Fatalf(\"readall err:%s\", err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// fill in response to current entry.Response\n\t\t\tif err := r.FillInResponse(); err != nil {\n\t\t\t\tlog.Printf(\"FillInResponse: %e\", err)\n\t\t\t}\n\n\t\t\tfmt.Printf(\"url: %s status: %s\\n\", r.Entry.Request.URL, r.Response.Status)\n\t\t}()\n\t}\n\n\t// Writes the contents of the internal har json object to IO\n\tif err := h.Write(io.Discard); err != nil {\n\t\tlog.Fatalf(\"write err:%s\", err)\n\t}\n\n\t// clean har\n\th.Reset()\n\tfmt.Println(\"entries:\", h.EntryTotal())\n\n\t// Output:\n\t// version: 1.2 create: \u0026{Name:WebInspector Version:537.36 Comment:} entries: 3\n\t// url: https://zh.wikipedia.org/wiki/.har status: 200 OK\n\t// url: https://www.baidu.com status: 200 OK\n\t// entries: 0\n}\n```\n\nPlease refer to [example_test.go](./example_test.go)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchaunsin%2Fgo-har","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchaunsin%2Fgo-har","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchaunsin%2Fgo-har/lists"}