MCPcopy
hub / github.com/purpleidea/mgmt / processResp

Method processResp

engine/resources/http_client.go:798–951  ·  view source on GitHub ↗

processResp runs the CheckApply work for an http response. It does everything that happens after the typical `!apply {}` stage, and after we've received an *http.Response. It's split out into a helper with this kind of type signature because we may process from a standalone CheckApply, or we may pro

(ctx context.Context, resp *http.Response, apply bool)

Source from the content-addressed store, hash-verified

796// http request to get the data for CheckApply! This runs the Close on the body.
797// This has the same return signature as what is used when running CheckApply...
798func (obj *HTTPClientRes) processResp(ctx context.Context, resp *http.Response, apply bool) (bool, error) {
799
800 defer resp.Body.Close()
801 if obj.init.Debug {
802 obj.init.Logf("resp: %v", resp)
803 }
804
805 // Did the http server tell us that our file is already just fine?
806 if resp.StatusCode == http.StatusNotModified && obj.MtimeCheck {
807 obj.init.Logf("file is up to date, skipping download")
808 content, err := obj.readAll()
809 if err != nil {
810 return false, err
811 }
812 if err := obj.send(content); err != nil { // send/recv
813 return false, err
814 }
815
816 // 304 means our on-disk data is still current. Record this as
817 // the outcome and let publishResponse decide what to do with
818 // the bridge. Usually it leaves the last captured value alone
819 // (so a steady stream of 304s never surfaces as a status), but
820 // it seeds a 200 on a fresh start where the bridge is empty.
821 obj.status = http.StatusNotModified
822 obj.output = obj.dst
823 return true, nil
824 }
825 if resp.StatusCode != http.StatusOK {
826 obj.status = resp.StatusCode // report the HTTP code (eg: 404, 500)
827 obj.output = ""
828 return false, fmt.Errorf("unexpected status: %s", resp.Status)
829 }
830
831 // TODO: are there more ways to early return with (true, nil) right now?
832
833 // In noop mode we must not write to disk. The server has content for us
834 // but saving it (writing the file) is a change we're not allowed to do.
835 if !apply {
836 // XXX: leave the obj.status / obj.output untouched rather than
837 // reporting a code for data we didn't actually capture?
838 // XXX: do we need to send/recv in noop mode?
839 return false, nil
840 }
841
842 // If we're writing a file, we should stream it to a vardir and then
843 // swap it atomically so that (1) we don't buffer the entire file into
844 // memory and (2) so that we don't have a partial (corrupt) file if the
845 // http fails to complete or validate the hash correctly. Note that we
846 // *don't* store the file twice in the steady state, since the vardir
847 // version overwrites the final destination when things check out okay.
848 tmpdel := true
849 defer func() {
850 // once file moved away, we should not run remove!
851 if !tmpdel {
852 return
853 }
854 // cleanup the partial file if not moved...
855 if err := os.Remove(obj.tmp); err != nil {

Callers 2

longpollCheckApplyMethod · 0.95
pollCheckApplyMethod · 0.95

Calls 15

readAllMethod · 0.95
sendMethod · 0.95
hashFileMethod · 0.95
WrapfFunction · 0.92
LogfMethod · 0.80
NewMethod · 0.80
SyncMethod · 0.80
CopyMethod · 0.65
GetMethod · 0.65
StringMethod · 0.65
CloseMethod · 0.45
RemoveMethod · 0.45

Tested by

no test coverage detected